11/21/2015

[SYSTEM HACKING] Binary 분석을 통해 Program에 포함된 숨겨진 데이터 찾아내기(Find Hidden Data for Application Hakcing)

일반적으로 Application 해킹에 대한 이야기는 리버싱으로 시작하여, 리버싱으로 끝나기 마련입니다.
대부분 디스어셈블러와 디버거를 이용하여 취약점을 분석하거나 내부 보안로직을 우회하는 등 프로그램에 대한 공격을 수행하게 됩니다.

오늘은 간단한게, Binary 파일 분석을 통해서 어플리케이션의 취약, 인증 우회 포인트를 찾는 방법에 대해 이야기할까 합니다.

대부분의 프로그램들은 매우 잘 만들어져 Binary 분석은 커녕 리버싱 자체로도 벅찬 경우가 있지만, 또 반대로 간단하게 Binary 분석을 통해 쉽게 풀어나갈 수 있는 프로그램도 있습니다.


아래 코드는 간단하게 Password 를 받아 비교하여, 결과를 주는 코드입니다.
코드를 보시면 알겠지만, strcmp 사용으로 취약할 수 있고, 단순한 코드여서 assemble를 통해 흐름을 바꾸어 쉽게 변조가 가능한 프로그램입니다.

#include <stdio.h>

#define db_id "admin"
#define db_pw "admin123"

void main()
{
 char user_pw[644];
 printf("input PW: ");scanf("%s",user_pw);
 if(!strcmp(db_pw,user_pw))
 {
  printf("\nOK Admin..\n");
 }
 else
 {
  printf("\nPW Error.\n");
 }


}



또한 추가로 간단한 문제점이 하나 있는데, 바로 #define을 사용하여 Password 값을 저장하고 있는 것 입니다.
프로그램 내 인증이나, 패스워드 등 중요한 데이터를 포함하고 있을 경우 hex editor로 확인이 가능합니다.

물론 ...  간단한 코드이기에 확인이 쉬운 것 뿐이지 큰 프로그램은 Binary로 분석하기 어렵습니다..ㅎㅎㅎㅎㅎㅎㅎㅎ

Test Code Compile & Execute


일단 테스트를 위해 컴파일합니다.

# gcc -o define_code define_code.c
# ll
합계 20
..snip..
-rwxr-xr-x  1 root   root   7287 11월 21 00:23 define_code
-rw-r--r--  1 root   root    251 11월 21 00:23 define_code.c


실행하면 아래와 같이 Password를 물어보고, 맞으면 OK Admin, 틀리면 PW Error를 노출하게 됩니다.

# ./define_code
input PW: www.codeblack.net

PW Error.

gHex(or hxd)를 통한 분석(Binary Analysis with HEX Editor)


ghex를 통해 한번 열어서 확인해보겠습니다. (윈도우에서는 대표적으로 hxd가 많이 사용되지요)
ELF로 시작하는 실행 파일입니다.



여기서 노출되었던 문자열 위주로 찾으면 조금 편합니다.
"PW Error" 문자열 기준으로 검색해시면 아래와 같이 찾아낼 수 있습니다. (다 쓰기보단 나눠서 찾는게 좋아요)



찾아낸 PW Error 문자열 주변으로 PW가 맞았을 때 메시지와 아까 우리가 지정한 Password 문자열을 확인할 수 있습니다.



물론 코드를 모르는 상태에서 보면 저게 뭔가 싶겠지만, 스크립트를 짜서 나름대로 분석하거나, 노가다를 통해서 어느정도 유추할 수 있는 부분이기에 프로그램 입장에서는 취약한 포인트를 하나 더 가지고 있는 상태입니다.

저련 형태로 단순 코딩된 데이터는 hex editor 이외에도 여러가지 툴들을 이용해 좀 더 쉽게 확인할 수 있습니다.


여담으로 테스트 코드로 대충 쓴거지만, 이 코드 자체가 매우 취약해서 .. objdump를 통해 확인했을 때 main 이외에 별다른게 확인되지 않고 흐름또한 단순하기 떄문에 gdb, edb 등을 이용해 쉽게 인증에 대해 통과할 수 있는 프로그램이 되겠네요.

# objdump -d define_code
000000000040060c <main>:
  40060c: 55                   push   %rbp
  40060d: 48 89 e5             mov    %rsp,%rbp
  400610: 48 81 ec 90 02 00 00 sub    $0x290,%rsp
  400617: bf 1c 07 40 00       mov    $0x40071c,%edi
  40061c: b8 00 00 00 00       mov    $0x0,%eax
  400621: e8 9a fe ff ff       callq  4004c0 <printf@plt>
  400626: 48 8d 85 70 fd ff ff lea    -0x290(%rbp),%rax
  40062d: 48 89 c6             mov    %rax,%rsi
  400630: bf 27 07 40 00       mov    $0x400727,%edi
  400635: b8 00 00 00 00       mov    $0x0,%eax
  40063a: e8 b1 fe ff ff       callq  4004f0 <__isoc99_scanf@plt>
  40063f: 48 8d 85 70 fd ff ff lea    -0x290(%rbp),%rax
  400646: 48 89 c6             mov    %rax,%rsi
  400649: bf 2a 07 40 00       mov    $0x40072a,%edi
  40064e: e8 8d fe ff ff       callq  4004e0 <strcmp@plt>
  400653: 85 c0                 test   %eax,%eax
  400655: 75 0c                 jne    400663 <main+0x57>
  400657: bf 33 07 40 00       mov    $0x400733,%edi
  40065c: e8 4f fe ff ff       callq  4004b0 <puts@plt>
  400661: eb 0a                 jmp    40066d <main+0x61>
  400663: bf 3f 07 40 00       mov    $0x40073f,%edi
  400668: e8 43 fe ff ff       callq  4004b0 <puts@plt>

strcmp 이후에 바로 jne, jmp가 있는 구간이 확인되고, 흐름을 바꾼다면 쉽게 가짜 패스워드로 통과할 수 있겠지요. :)

(gdb) set disassembly intel
(gdb) disas main
Dump of assembler code for function main:
   0x000000000040060c <+0>: push   rbp
   0x000000000040060d <+1>: mov    rbp,rsp
   0x0000000000400610 <+4>: sub    rsp,0x290
   0x0000000000400617 <+11>: mov    edi,0x40071c
   0x000000000040061c <+16>: mov    eax,0x0
   0x0000000000400621 <+21>: call   0x4004c0 <printf@plt>
   0x0000000000400626 <+26>: lea    rax,[rbp-0x290]
   0x000000000040062d <+33>: mov    rsi,rax
   0x0000000000400630 <+36>: mov    edi,0x400727
   0x0000000000400635 <+41>: mov    eax,0x0
   0x000000000040063a <+46>: call   0x4004f0 <__isoc99_scanf@plt>
   0x000000000040063f <+51>: lea    rax,[rbp-0x290]
   0x0000000000400646 <+58>: mov    rsi,rax
   0x0000000000400649 <+61>: mov    edi,0x40072a
   0x000000000040064e <+66>: call   0x4004e0 <strcmp@plt>
   0x0000000000400653 <+71>: test   eax,eax
   0x0000000000400655 <+73>: jne    0x400663 <main+87>
   0x0000000000400657 <+75>: mov    edi,0x400733
   0x000000000040065c <+80>: call   0x4004b0 <puts@plt>
   0x0000000000400661 <+85>: jmp    0x40066d <main+97>
   0x0000000000400663 <+87>: mov    edi,0x40073f
   0x0000000000400668 <+92>: call   0x4004b0 <puts@plt>
   0x000000000040066d <+97>: leave
   0x000000000040066e <+98>: ret






HAHWUL

Security engineer, Gopher and H4cker!

Share: | Coffee Me:

0 개의 댓글:

Post a Comment