2013년 8월 27일 화요일

BOF 원정대

BOF 원정대

1. Download VM image

2. Open & BOOT: linux-up

- gate/gate

int main(int argc, char *argv[])
{
    char buffer[256];
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}

$gdb gremlin

(gdb) set disassembly-flavor inte
(gdb) disassemble main

Dump of assembler code for function main:
0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %ebp,%esp
0x8048433 <main+3>:     sub    %esp,0x100
0x8048439 <main+9>:     cmp    DWORD PTR [%ebp+8],1
0x804843d <main+13>:    jg     0x8048456 <main+38>
0x804843f <main+15>:    push   0x80484e0
0x8048444 <main+20>:    call   0x8048350 <printf>
0x8048449 <main+25>:    add    %esp,4
0x804844c <main+28>:    push   0
0x804844e <main+30>:    call   0x8048360 <exit>
0x8048453 <main+35>:    add    %esp,4
0x8048456 <main+38>:    mov    %eax,DWORD PTR [%ebp+12]
0x8048459 <main+41>:    add    %eax,4
0x804845c <main+44>:    mov    %edx,DWORD PTR [%eax]
0x804845e <main+46>:    push   %edx
0x804845f <main+47>:    lea    %eax,[%ebp-256]
0x8048465 <main+53>:    push   %eax
0x8048466 <main+54>:    call   0x8048370 <strcpy>
0x804846b <main+59>:    add    %esp,8
0x804846e <main+62>:    lea    %eax,[%ebp-256]
0x8048474 <main+68>:    push   %eax
0x8048475 <main+69>:    push   0x80484ec
0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    %esp,8

2013년 8월 22일 목요일

[Write-Up] May the HeXA with you

HeXA 1st CTF Rev 300

May the HeXA with you

Download

link : https://www.dropbox.com/s/rypuwxcpj8taj6r/HeXATalk.apk

Category

  • network
  • coding

Description (http://goo.gl/HUsdRA)

A long time ago in a galaxy
far, far away...

Episode VII
May the hexa with you

It is a dark time for the Rebellion. Although the Death Star has been destroyed, Imperial troops have driven the Rebel forces from their hidden base and pursued them across the galaxy.

To overcome this serious crisis, Rebellion request for a hacker group, HeXA, to develope an encrypted  network. Therefore, HeXA start work on the new project named HeXATalk.

However, just before the completion of HeXATalk, Imperial's assassin killed all the members of HeXA except you. Rebellion, who must get a secret message from Luke Skywalker, need you to complete the unfinished HeXATalk and find out what the secret message is.

Write-Up


  1. unzip apk
  2. extract jar with dex2jar : $dex2jar HeXATalk.apk
  3. jar analysis



source code : hexa.per.sh.hexatalk.MainActivity$p

package hexa.perl.sh.hexatalk;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.util.Log;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Random;

class MainActivity$p extends AsyncTask
{
  private MainActivity$p(MainActivity paramMainActivity)
  {
  }

  @SuppressLint({"NewApi"})
  protected Void doInBackground(Void[] paramArrayOfVoid)
  {
    try
    {
      if (InetAddress.getByName(this.this$0.HOST).isReachable(1000))
      {
        this.this$0.suc = true;
        ByteBuffer localByteBuffer = ByteBuffer.allocate(30);
        localByteBuffer.order(ByteOrder.LITTLE_ENDIAN);

        // localByteBuffer1 = 4바이트 int (인덱스)
        localByteBuffer.putInt(0, this.this$0.idx);
        char[] arrayOfChar1;

        int i; // 인덱스
        if (this.this$0.idx == 1)
        {
          arrayOfChar1 = new char[] { 108, 111, 103, 105, 110 }; // char[] 'login'
          i = 0;
          if (i < arrayOfChar1.length); // 첫번째 단계
        }
        while (true)
        {
          // 소켓 연결
          MainActivity.access$0(this.this$0, new Socket(this.this$0.HOST, this.this$0.PORT));
          MainActivity.access$2(this.this$0, MainActivity.access$1(this.this$0).getInputStream());
          MainActivity.access$3(this.this$0, MainActivity.access$1(this.this$0).getOutputStream());
          MainActivity.access$4(this.this$0).write(localByteBuffer.array());
          MainActivity.access$4(this.this$0).flush();
          this.this$0.wsize = MainActivity.access$5(this.this$0).read(this.this$0.w);
          MainActivity localMainActivity = this.this$0;
          localMainActivity.idx = (1 + localMainActivity.idx);
          MainActivity.access$6(this.this$0);
          return null;
          int j = i + 4;

          // localByteBuffer = 4바이트 int (인덱스) + char[] 'login' (커맨드)
          localByteBuffer.put(j, (byte)arrayOfChar1[i]);

          i++; // 인덱스 증가
          break;
          if (this.this$0.idx == 2) // 두번째 단계
          {
            String str = new String(this.this$0.w, 0, this.this$0.wsize);

            // 서버로부터 받은 메세지 => port : xxxxxxx
            // this.this$0.PORT = xxxxxxx (새로 할당받은 포트번호)
            this.this$0.PORT = Integer.parseInt(str.substring(3 + str.indexOf(" : ")));

            char[] arrayOfChar2 = { 98, 117, 121 }; // char[] 'buy'
            for (int k = 0; ; k++)
            {
              // 루프 마지막에 한번
              if (k >= arrayOfChar2.length)
              {
                this.this$0.aes_key = new byte[16];
                new Random().nextBytes(this.this$0.aes_key);

                // aes_key에 랜덤 바이트 할당
                for (int m = 0; m < this.this$0.aes_key.length; m++)
                  localByteBuffer.put(m + 14, this.this$0.aes_key[m]);

                // localByteBuffer = 4바이트 int (인덱스) + char[10] 'buy' (커맨드) + aes_key (랜덤 바이트 AES 키)
                break;
              }

              // localByteBuffer = 4바이트 int (인덱스) + char[4] 'buy' (커맨드)
              localByteBuffer.put(k + 4, (byte)arrayOfChar2[k]); 
            }
          }
          if (this.this$0.idx == 3) // 세번째 단계
          {
            // 완성되지 않은 코드 = 서버로부터 데이터를 받는 부분
            // 4바이트 int (암호화된 데이터 크기) + AES/CBC/PKCS7Padding 암호화된 데이터
            Log.d("HeXA", "need to read  4byte ([x] = size of encrypted data) + [x] byte ( AES/CBC/PKCS7Padding encrypted data )");
            byte[] arrayOfByte = new byte[16];
            arrayOfByte[0] = 104;
            arrayOfByte[1] = 101;
            arrayOfByte[2] = 120;
            arrayOfByte[3] = 97;
            arrayOfByte[4] = 102;
            arrayOfByte[5] = 111;
            arrayOfByte[6] = 114;
            arrayOfByte[7] = 101;
            arrayOfByte[8] = 118;
            arrayOfByte[9] = 101;
            arrayOfByte[10] = 114;
          }
        }
      }
    }
    catch (Exception localException)
    {
      while (true)
      {
        this.this$0.suc = false;
        continue;
        this.this$0.suc = false;
      }
    }
  }
}

4. coding


import socket
import sys
import struct
import time
from Crypto.Cipher import AES
from pkcs7 import PKCS7Encoder

encoder = PKCS7Encoder()

def enc_aes(data):
    iv = struct.pack('<16s','hexaforever')
    aes = AES.new(key=aes_key, mode=AES.MODE_CBC, IV=iv)
    pad_text = encoder.encode(data)
    cipher = aes.encrypt(pad_text)

    return cipher

def dec_aes(data):
    iv = struct.pack('<16s','hexaforever')
    aes = AES.new(key=aes_key, mode=AES.MODE_CBC, IV=iv)
    pad_text = aes.decrypt(data)
    plain_data = encoder.decode(pad_text)

    return pad_text

HOST = "10.xx.xx.xx"
PORT = xxxx

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))

data = " ".join(sys.argv[1:])

idx = 1
data = struct.pack('<I', idx)
data += struct.pack('<10s','login')

sock.sendall(data + "\n")
received = sock.recv(1024)
sock.close()

print "Sent:     {}".format(data)
print "Received: {}".format(received)

port = received.split(" : ")[1]
print "port : " + str(port)

#print "sleep for 3 sec"
#time.sleep(10)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, int(port)))

aes_key='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
idx = 2
data = struct.pack('<I', idx)
data += struct.pack('<10s','buy')
data += aes_key

sock.sendall(data + "\n")
data = sock.recv(1024)
print data
sock.close()

size = struct.unpack('<I',data[:4])[0]
print "SIZE : " +str(size)
print dec_aes(data[4:4+size])

print "Received: {}".format(received)

Missing code


ByteBuffer bB = ByteBuffer.allocate(4);
bB.order(ByteOrder.LITTLE_ENDIAN);
bB.put(Arrays.copyOfRange(w, 0, 4));

int size = ByteBuffer.wrap(bB.array()).order(java.nio.ByteOrder.LITTLE_ENDIAN).getInt();

byte[] iv = new byte[] { 0x68, 0x65, 0x78, 0x61, 0x66, 0x6f, 0x72, 0x65, 0x76, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00 };

javax.crypto.spec.SecretKeySpec keyspec = new javax.crypto.spec.SecretKeySpec(aes_key, "AES");
javax.crypto.spec.IvParameterSpec ivspec = new javax.crypto.spec.IvParameterSpec(iv);

javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] decrypted = cipher.doFinal(Arrays.copyOfRange(w, 4, 4 + size));

String key = new String(decrypted);

2013년 8월 18일 일요일

[카카오톡] python wrapper for LOCO protocol


pypi : https://pypi.python.org/pypi/kakao

kakaotalk module is a python wrapper for LOCO protocol.
You can install this module using pip:
$ pip install kakao
$ easy_install kakao
This project is very much based on the LOCO Analysis from  bpak.org.

Quick Start Guide

Requirement

First of all, you need a KakaoTalk account. Then, you have to find out 'duuid', 'sKey', and 'user_id' for your KakaoTalk account. If you need some help to extract these info from your account, see this post. When you are prepared, you need to specify these info to kakaotalk module. For example:
from kakao import kakao

kakao.duuid = 'YOUR_DUUID'
kakao.sKey = 'YOUR_SKEY'
kakao.user_id = 'YOUR_USER_ID'

After you prepared

There are various kinds of commands in LOCO protocol like 'login', 'write', 'read', 'buy', 'checkin' etc. To use these commands freely, you have to follow two steps to make proper connection with LOCO server.
  1. First, send 'checkin' command to get LOCO server info (host and port) to communicate.
    document = checkin()
    
    host = document['host']
    port = document['port']
    
  2. Send handshake socket with 'login' command to LOCO server with encryption info.
    h = hand()
    l = login()
    enc_l = enc_aes(l)
    command = struct.pack('I',len(enc_l)) + enc_l
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((str(host),port))
    s.settimeout(5)
    
    s.send(h + command)
    reply = s.recv(40960)
    
Instead of using those codes, you can just simply use start() function :) For example:
s = kakao.start()
suc = kakao.write(s, chatId, "(하트)")

Commands

  • buy : get LOCO server information(HOST,PORT) from KakaoTalk
  • checkin : literaly check in to the LOCO server
  • cwrite : create chat room and send message
  • write : send message to specific chat room
  • hand : handshake command which contains encryption information
  • login : notify to LOCO server that you will use commands (not sure)
  • chaton : notify to LOCO server that you will start to chat with specific chat room
  • nchatlist : get chat room list from LOCO server (not sure)
  • leave : leave the specific chat room
  • ping : send ping to server that notify you are still alive
  • upseen : notify that you are checked specific chat room
  • read : get chat room list and info from server
Application

HeXA bot

License Information

The MIT License (MIT)
Copyright (c) 2013 Kim Tae Hoon

2013년 8월 6일 화요일

[카카오톡] 헥사봇


* 2014.01.13 Announcement *

The End :)



* 2013.12.12 Announcement *


'carpedm20'으로 검색이 허용되지 않는것으로 보입니다.

현재로서는 지인을 통해 친구 추가하시는 방법밖에 없어 보입니다.

It is not possible to search HeXA Bot with 'carpedm20'.

The only way to make HeXA Bot as your friend is getting some help from your friends.



HeXA Bot is a robot which automatically answer to user's command through KakaoTalk.

Facebook : https://www.facebook.com/photo.php?fbid=468189449939384
HeXA : http://hexa.us.to/

Analysis of LOCO protocol : http://carpedm20.blogspot.kr/2013/07/loco.html

ps. https://pypi.python.org/pypi/kakaotalk
ps2. pip install kakaotalk