이번 주에는 취약점 검사 방법의 변천사와 현재 트렌드, 핀툴에 대하여 깊게 파고드는 시간을 가졌다.
사실 취약점 검사 방법의 변천사, 현재 트렌드 들은 후반 부 밖에 듣지 못하였다...
시간 계산을 잘못해서 너무 늦게 나와서 20분~30분을 늦어버렸다...
취약점 찾는 기법의 변천사
소스코드 오디팅
[Vulnerable functions]
-> strcpy , memcpy , gets , fges , printf
api usage 탐색
-> cat program.c | grep strcpy
후킹
-> Vulnerable functions에 유저 인풋이 들어가는지 체크
퍼징
-> valid한 유저인풋을 bit flipping이나 구조를 약갘씩 변경해 주면서
다양한 code path를 탐색하면서 특정 값이 취약한 루틴에 들어갈 때
발생하는 취약점을 찾는 확률적인 취약점 검사 기법
taint progation analysis
-> 유저인풋의 data flow를 죄다 트래킹해서
destination, soruce, instruction pointer 등에 영향을 주는 포인트를 알아낸
tainted destination
tainted source
tainted instruction pointer
-> taint == 오염시키다
-> 모든 취약점은 유저인풋으로 나온다
-> hwp.exe exploit.exe
hwp.exe -> CreateFile | OpenFile(“exploit.exe”)
-> ReadFile(hFile, buf, 65535); -> tainted : buf
-> 표를 뜻하는 opcode ==> tainted
handler_table[opcode](section_data)
-> call handler_table(, eax, 4) ==> eax : tainted
-> handler_table + eax*4
dynamic binary instrumentation
-> Pintool , libdft
symbolic executionn —> KLEE & constraint solver —> z3
-> path explosion
-> scalable 하지 않다는 단점 존재
concolic execution
—> concrete execution + symbolic execution
conc(rete) + (symb)olic
path analysis | 1day analysis
—> binary | source code diffing
vulnerability extrapolation —> fabian yamaguchi
코드 유사도 비교를 통한 취약점 분석
key concept:
기존에 취약하다고 알려진 코드 패턴이 다른 코드베이스에서도 발견이 될 경우 그 코드도 취약할 가능성이 높음
jaccard similarity coefficient algorithm
hausdorff similarity
나는 symbolic executionn 에서 부터 들어서 위에 부분을 자세히 모른다..
젠장 ㅠㅠ;
그나마 뒷 부분에서 알아들은 내용이라곤 코드 유사도 비교를 통한 취약점 분석 부분이였다.
예~~전에 문장 유사도 알고리즘을 발견해서 보면서 구현하고 깃허브에 올린 게 기억이 나는데.
이것은 여러 방법들이 있지만 cd80니뮤 말씀하신 방법은 이러하였다.
(잘 기억이 안나지만 이러했던걸로 기억남..)
하이레벨 코드로 변환해서 그 코드들을 함수에 임의로 지정한 숫자들을 그래프로 표시하여
원본 소스와 비교할 소스와 그래프로 비교하여 유사도를 확인한다고 했다.
꽤 흥미로웠었다.
그 뒤에는 핀툴에 대해 jinmo123니뮤 가르쳐주셨는데...
솔직히 알아들은게 없었다고 해도 다를 께 없었다..
ㅂㄷㅂㄷ;;
뭐 일단 대충 어떤식으로 동작을 하는 지 그 부분까지는 이해했는데.
그 뒤부터는 귀로 들어오질 않았다...ㅂㄷㅂㄷ;
설치부터 막혀버린 나의 상황이 너무 안타깝다..
뭐 그래도 이번 주는 시간이 워낙 많으니 삽질할 시간이 많아서
구글링을 통해 사용법을 터득할 예정이다.
터득한 뒤에 자세히 정리를 하여 올려봐야겠다.
일단 설치부터... [a-z] 까지 최대한 적어보자!
일단 Pin tool 설치는 간단하다.
http://pintool.org 사이트에 접속하면 Downloads 버튼이 나와있다.
Pin 은 의외로 지원하는 OS가 있다.
환경에 맞게 다운로드를 하면 되는 것이다.
지원 OS : Linux, MAC, WINDOWS, ANDROID, XEON PHI
사실 나는 XEON PHI 가 뭔지 모른다. ㅋㅋ !
뭐 하여튼 페이지에 접속을 하면 이런 페이지가 반겨준다.
다운로드 페이지로 가보자.
들어가보면 여러 OS들이 반겨주고 있다.
WINDOWS 같은 경우에는 컴파일러 킷이라는 게 여러게 있는데.
VC10~VC12 들이 있는데.
VC 10 : VS2010, VC11 : VS2011, VC12 : VS2013 이라고 한다.
뭐 이렇게 있는데
본인은 최근에 올라온 녀석으로 받았습니다.
이제 압축을 풀어줍시다.
tar -xzvf pin-2.14-71313-gcc.4.4.7-linux.tar.gz
하시면 마아아악 압축이 풀립니다.
사실 저는 이 부분에서 무려 3시간 삽질을 했으나...
문제는 gcc 버전도 아니였으며 우분투 버전의 문제였습니다.
아마도 우분투 버전이 너무 높아도 안되는 것 같네요...ㅠ;
그래서 본인은 처음 우분투 버전 15.10 에서 14.04 로 재설치를 했습니다. ㅠㅠ
그래서 결국 성공했던 버전들의 정보는 이러합니다.
넵.
32bit, 64bit 둘 다 했습니다.
혹시 모를 상황을 위해서 말이죠!
뭐 하여튼 이제 빌드를 해보죠
일단 pin-2.14-71313-gcc.4.4.7-linux/source/tools/MyPinTool 경로에 가시면 이러한 파일들이 있습니다.
source/tools 에는 온갖 샘플 예제코드들이 존재합니다.
필요한 것을 빌드해서 사용하면 된다고 합니다.
만약 32bit 일 경우에는 make all TARGET=ia32 를 해줘야된다고 하네요.
왜 그런지 물어보시면 메뉴얼에 그렇게 적혀있습니다 !
32bit:
64bit:
빌드의 결과물은 so 파일이 됩니다.
이제 이 so 파일을 사용하시면 됩니다.
사용 방법
pin -t [so파일경로] -- [분석대상프로그램경로]
pin -t <컴파일 경로> -- /bin/ls -- 리눅스
밑에 /bin/ls 를 주는 이유는 /bin/ls 를 실행하면서 중간에 코드를 원하는 대로 추가할 수 있기 때문이다.
사실 이놈의 에러때문에 시간을 다 날려 먹었다고 해도 과언이 아니다. ㅎㅎ!
이러한 에러 때문에 엄청~~ 애먹었다.
gcc 버전도 낮춰보고 ~
별 짓을 몇 시간 동안하며 jinmo123니뮤한테 찡찡거리기도 했는데
해결 방법을 주지 않으셨다고 한다... ㅂㄷ
아마 바쁘셨나봄 ㅎㅎ
그래서 다른 친구들에게 물어보니 내가 다른 친구들보다 gcc 버전과 우분투 버전이 엄청 나게 높음을 알 수 있었다.
그래서 만약에 에러가 난다면 자신의 gcc 버전이나 우분투 버전을 한번 의심해보아야한다.
또는 g++ 이 설치가 되있지 않아서 에러가 날 수도 있다.
에러 명은 구하지 못했으므로 딱 봐도 g++ 이 없어서 에러가 나는 것을 알 수 있을 것이다...
그럴때에는 sudo apt-get install g++ 를 한 뒤에 컴파일 해주면 해결이 된다.
이런 것 때문에 3시간이나 날려먹었다.
ㄱㅇㄷ
본격적으로 핀툴을 사용해보자.
처음에 이 핀툴 사용 방법에 매우 애를 먹었다...
ㅂㄷㅂㄷ;;
어떻게 쓰는지 알 수가 있어야지...원...
그래서 핀툴 사이트에 메뉴얼 소스를 이용하면서 사용 방법을 터득했다.
굳이 사이트 메뉴얼에 안가도 이 경로에 소스들이 있다.
바로 빌드해서 사용하면 된다!!
완전 꿀...!
inscount0.cpp
이 프로그램에서 실행되는 명령어 전체 개수를 카운트합니다.
inscount0.so 파일이 잘 빌드 됬는지 확인하시고.
빌드하시는 법을 모르겠다면 위에 적어둔 1. Pin Tool Building 을 다시 읽어보시는 것을 추천드립니다!
$ pin -t so 파일 경로 -o 결과 로그 뱉을 파일 이름.log -- 분석할 프로그램 경로
요래 실행을 하시면 됩니다.
로그를 보시면 실행되는 명령어 전체 개수 카운트 값이 저장되있을 겁니다!
넵 수고하셨습니다.
이제 코드를 구경해보러 가보죠!
요시.
jinmo123 Pintool Homework
과제.zip
요시 시작해보자.
일단 아이다로 열어서 헥스레이를 해보려고 했었었다.
결과... 어... 역시...헥스레이로는 안된다는 것을 깨달았다.
일단 그러면!
그냥 어셈 코드로 보자!!
음...어마어마한 값들을 알아내야된다는 것에 걱정이 ... 컷었습니다..
사실 얼마 안되면 손으로 하려고 했는데
아니...이건 뭐...ㅂㄷㅂㄷ;
일단 0804821E 에서 READ 를 받습니다.
그 뒤에 어마엄아멍마암어마아한 movsx, xor , cmp, jnz 들이 이루어집니다.
이 모든 것이 맞을 경우에 "축하해!" 를 띄워줍니다.
자! 이제 핀툴을 사용해서 소스를 짜면 됩니다!
일단 문제 풀 아이디어는 이러했습니다.
cmp로 비교하는 부분만 맞추면 챠르르륵 넘어가는 부분이기 때문에!
eax = ??
eax ^ 0x0C7
cmp eax, 0x0FE
a^b = c
a^c = b
b^c = a
a = eax
b = 0x0C7
c = 0x0FE
b^c = a
이러하면 원래의 값을 구할 수 있기 때문에!
xor, cmp 뒤의 값을 긁어와서 다시 xor 한 값을 저장하면 되겠구나! 싶었습니다!
그러나 이상한 다른 곳의 값을 긁어올 수 있을 것 같아 딱 원하는 주소 영역을 정해줬습니다.
#define start 0x8048223
#define end 0x80A3778
그리고 현재의 주소를 알아낼 필요가 있었습니다.
현재 명령의 주소를 리턴해주는 녀석을 발견했습니다.
일단 현재 코드 상태입니다.
일단은 주소를 잘 뱉어주는 지 확인해보도록 하겠습니다!
실행해보았습니다.
무언가를 마아아악 뱉어주네요.
134513120
>>> hex(134513120)
'0x80481e0'
ㅇㅋ
주소는 잘 가져옵니다!
그러면 이제 원하는 코드 영역에 있는 녀석들만 긁어올 수 있게 처리를 해줍시다!
ㅇㅋ
이제 그 명령의 opcode를 긁어오죠 !
ㅇㅋㅇㅋ
뭐 대충 요래조래 이용해서
이렇게 확인도 했었습니다.
그렇다면 이제 xor, cmp 의 값을 긁어오도록 하죠!
그리고 xor, cmp 의 값을 담아 둘 변수도 선언해줬습니다.
제가 저 때 왜 저런 이미지의 역활을 하는 걸 만들었는지 기억은 안나지만...
서브라임텍스트에서
MOVSX
XOR
CMP
JNZ
을 리플렉스 공백을 하니 CMP 들 혼자서 남는 부분이 있었습니다.
이때 아..! XOR 말고도 그냥 CMP 로만 비교하는 부분이 있구나! 싶었습니다.
그래서 XOR이 전에 없을 경우에는 CMP 값만 긁어와야되기 때문에 이에 대한 스위치 변수도 만들었습니다.
그래서 일단 그 명령 부분의 imm을 긁어와야되는데!
예아 발견했습니다.
리턴 값을 잘 보고 자신에게 필요한 것을 쓰면 될 것 같습니다! 예아!
중간 점검
예아!
이제 cmp 부분에서 스위치가 켜져있으면 xor^cmp
스위치가 안켜져있으면 cmp 그냥 넣으면 됩니다!
코딩 ㄱㄱ!
이제 실행해보고 결과가 어떻게 나오는 지 봅시다.
ㄱㄱ
잘 뱉어냈습니다.
근데 이상하게 숫자로 뱉어냈네요.
분명 문제 낼 때 키는 base64 decode 20 번 하시면 됩니다 ㅎㅎ 라고 했는데...
아! 아스키 코드로 문자열로 만들면 되겠다! 라고 뒤 늦게 생각했습니다.
ps. 어제 너무 피곤해서 이걸 생각 못 해서 출제자형께 페메로 테러 했었음 ㅎ!
그러면 코드 수정 ㄱㄱ!
그리고 실행 ㄱㄱ!
그리고 플래그를 읽으면...!
이 문자열들을 decode 20번 해주면!
과제 끝!
매우 좋은 경험이였따...
그러하다.