오기로 풀어낸 문제이다.

쉘코드를 만들어주는 파이썬 모듈을 이용하면 편하다고 했지만
나는 내가 만들기 시작한거 내가 직접 만들어서 풀고싶었다.

밤을 새서 찾아보다가 자고 일어나니 리버싱에서 배웠던 기술이 생각이나 문제를 해결할 수 있었다.

asm 문제이다.



(asm)



문제 화면은 이렇다.


(문제 화면)



쉘코드를 만들으라는 것 같다.

문제는 flag 파일 이름이 너무 긴것...



(긴 flag)



sym 링크를 쓰고 싶었지만 chroot로 인해 링크 걸어봤자 소용 없었다.

즉 저 긴 문자열을 쉘코드 안에 넣어야한다는 것...
하도하도 생각하다가 리버싱 공부하면서 배운 기술이 생각났다.

바로 call !!
call 명령어로 아래로 쭉 내려간다 이때 rip를 스택에 저장하고 가는 걸 이용한느 것이다.


(구성한 모습)



뒤에는 문자열들을 입력해준다.

그렇게 되면 엉뚱한 명령어로 인식이 되는데 상관없다. 나는 call을 이용해 이녀석들을 내려갈거기 때문에



(call 사용)



call 을 사용해서 아래로 내려간다.

그런데 올리디버거에서 쓰는거랑 직접 gdb를 이용해 코드를 보니 조금 달라서 직접 asm 를 만들어 테스트해보았다.



(테스트)



테스트 하면서 안 사실!
e8 은 call 명령어 이고
뒤에 0d 만큼 떨어진 곳으로 call 하게 되는 것!

그렇다면 나는 e8 을 이용해 100 떨어진 곳으로 이동시킬 것이다.



(call binary)



그 후 살짝의 미스매치가 있으므로 Nop 코드로 쿠쎤을 깔아준다.



(쿠쎤)



그 후 pop rsi 를 시작하여 open, read, write 함수를 호출하는 코드를 붙이면 끝!




(테스트)




(테스트 성공)



테스트 성공! 기분이 좋다.



(공격도 성공)



공격도 성공하니 기분이 더더 좋다!

'WarGame > 500 Project' 카테고리의 다른 글

(58/500) pwnable.kr - fsb  (0) 2017.08.12
(57/500) pwnable.kr - ascii_easy  (2) 2017.08.09
(55/500) pwnable.kr - uaf  (0) 2017.07.12
(54/500) pwnable.kr - cmd1  (0) 2017.07.12
(53/500) pwnable.kr - blackjack  (0) 2017.07.12


10번째 푼 문제이다! 

이름은 md5 password 이다.


(md5 password)



아래는 문제 페이지이다.




(문제 페이지)



비밀번호를 입력하는 칸이 하나 나온다.

소스코드를 보면 해시된 값을 넣어 테이블에서 select 검색을 한다.
그런데 조금 이상한 점이 있다.



(소스코드)



바로 md5 해시 함수에서 2번째 인자로 true를 주었다는 것이다.

기본적으로 디폴트 값은 default 이다.
이 값이 true로 넘어가게 되면 출력이 바이너리로 출력되게 된다. 근데 이게 바로 취약할 수 있다는 것이다. 해시 되는 과정에서 ' (싱글쿼터) 등 공격자가 필요한 특수문자를 만들어낼 수 있기 때문이다.

우리가 원하는 값은 '=' 이 값이 있으면 된다. 왜냐?
쿼리문장에서 where password='sdfds'='gfgfg' 
이런식으로 만들어주어 이렇게 되면 참으로 출력이되어 모든 값이 출력되기 때문이다.

예를들어 아래와 같이


(원하는 해시값)



우리가 원하는 해시값이다.

이렇게 나오는 저 값을 입력하게 되면 로그인이 되고 플래그가 나오게 된다.



(문제 해결)


'WarGame > 500 Project' 카테고리의 다른 글

(12/500) Wargame.kr - tmitter  (0) 2017.04.15
(11/500) Wargame.kr - type confusion  (0) 2017.04.15
(9/500) Wargame.kr - md5_compare  (0) 2017.04.13
(8/500) Wargame.kr - fly me to the moon  (0) 2017.04.13
(7/500) Wargame.kr - WTF_CODE  (0) 2017.04.12


시스템 공부에 들어서면서
바이너리 분석에 들어가 볼 것이다.

* 바이너리(실행파일)란?
 - 우리가 흔히 보는 윈도우즈의 .exe 확장자의 실행파일이라고 생각하면 된다.
 - 0과 1로 되어있는 기계어로 번역되있는 파일이다.

이 바이너리분석을 하기 위해서는 실행 파일이 어떻게 만들어지는지 공부할 필요가 있다.
즉,
다시말하면
프로그래밍된 코드가 어떻게 기계어로 번역되는지 이런 과정을 크게 Compile이라고 한다.
이 Compile 과정에 대해 알아보겠다.
우리는 C언어로 작성된 코드가 실행파일이 되는 과정을 살펴볼 것이다.

먼저! 간단하게 C코드를 작성한다. 



(sample.c 작성)



* gcc는 확장자를 보기 때문에 파일 이름 뒤에 .c를 붙여줘야한다.

만든 후 gcc를 이용해 컴파일을 해볼 것이다. gcc는 GNU C Compiler의 약자로 리눅스에서 제공하는 컴파일러이다.
아래처럼 컴파일 해본다.



(컴파일)



컴파일 완료되면 위와 같이 실행파일이 생성된것을 확인 해 볼 수 있다.
또 이 실행파일을 실행시키면 우리가 작성한 대로 Hello World 문구가 나오는 것을 확인 할 수 있다.

이 실행파일은 바이너리로 되어있기 때문에 vi 편집기 혹은 cat으로 볼 수 없고
헥스값을 볼 수 있는 xxd 데몬을 이용해서 볼 수 있다.



(바이너리 파일)



* gcc 뒤에 -o 옵션을 주어 우리가 원하는 파일이름으로 컴파일하여 실행파일을 만들 수 있다.



(-o 옵션)



* gcc 뒤에 -v 옵션을 주면 컴파일 과정이 화면에 그대로 출력된다.
우리는 gcc -v 옵션을 주어 컴파일이 이루어지는 과정을 그대로 살펴볼 것이다.



(-v 옵션)



위 화면을 보면 컴파일 과정이 주르르륵 나온 것을 볼 수 있다.
하나하나 과정을 짚어가며 살펴보겠다.

* 컴파일 과정

(1) 전처리 과정 : 컴파일 중 가장 먼저 이뤄지는 작업으로 매크로, #include 문장 해석을 한다.
전처리 : precompile


출력 화면에 해당하는 문구

 /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/cpp -lang-c -v -undef -D__GNUC__=2 -D__GNUC_MINOR__=91 -D__ELF__ -Dunix -Di386 -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__i386__ -D__linux__ -D__unix -D__i386 -D__linux -Asystem(posix) -Asystem(unix) -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__tune_i386__ sample.c /tmp/ccmsu4yd.i



cpp -> 전처리기이다. 즉 cpp명령이 보이고 뒤에 -어쩌구들 해서 많은 옵션들이 보인다. 뒤에


sample.c /tmp/ccmsu4yd.i 이 보이는데 sample.c를 임시디렉터리에 .i파일을 만드는 과정이다.


하지만 /tmp 디렉토리에 들어가면 .i 파일을 확인할 수 없는데 그 이유는 컴파일이 끝나면 삭제시키기 때문이다. 우리는 이 파일들을 보면서 확인할 것이므로 이러한 파일들이 삭제되지 않는 추가적인 옵션을 주어야한다.

-save-temps 옵션을 주어 임시파일 .i 파일을 삭제 하지 않게 하겠다.



(-save-temps 옵션)



옵션을 추가하니 여러 부산(?)물들 파일이 생긴것을 확인 할 수 있다.

우리가 먼저 확인해볼 것은 sample.i (전처리 과정에서 생기는 파일) 이다.!



(sample.i 파일)



큰 변화가 없어보인다?...

전처리 과정에서 어떤 일이 일어나는지 직접 눈으로 확인해보기 위해 c코드를 조금 수정해보겠다.!
define문장을 추가해보자!



(define 문장 추가)




다시 컴파일 하겠다!




(재컴파일)



재컴파일 후
sample.i 파일을 확인해본다.



(sample.i 파일)



- define 문장이 사라지고 소스코드 안에 썻던 define이 100(우리가 설정했던 값)
으로 모두 치환되어 있는 것을 확인 할 수 있다.
-> 바로 이게 전처리기의 역할이다.

2. 어셈블 과정 : 전처리된 파일을 어셈블리 형태로 변환

해당 문구

 /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/cc1 /tmp/ccmsu4yd.i -quiet -dumpbase sample.c -version -o /tmp/cc0q9vPg.s


.i 파일을 .s 파일로 바꿔준다. 이때 어셈블(기계어)형태로 바꿔준다.

왜 기계어라고 해도 무관하냐면 어셈블언어와 기계어가 1:1로 매칭되기 때문에 어셈블언어를 기계어라고도 한다. 즉 바이너리로 바꾸기 직전의 파일 .s 파일을 만들어준다.



(sample.s 파일)



sample.s 파일을 확인해보면 어셈블 언어로 바뀐것을 확인할 수 있다.

3. 컴파일 과정 : 어셈블 파일을 기계어(숫자)로 번역하는 과정이다. 정확히말하면 컴파일 과정은 이부분이지만 크게 말해 이 모든 과정을 컴파일이라고 통상적으로 말하곤 한다.

해당문구

as -V -Qy -o /tmp/ccs3N70j.o /tmp/cc0q9vPg.s


as : 어셈블러를 뜻한다. 즉 as 명령으로 -o옵션으로 .s파일을 .o 파일로 만든다.
.o 파일 (기계어로 뽑아낸 파일, 오브젝트 파일)



(sample.o 파일)



파일을 보면 이제부터는 vi 편집기로 볼 수 없다. 이제부터는 바이너리이기 때문에 xxd 혹은 objdump 등 바이너리를 다루는 도구를 통해 봐야한다. objdump를 이용해 확인해보겠다.



(sample.o 파일 확인)



파일을 보면 .s 파일에서 봤던 어셈블 언어가 모두 바이너리로 바뀐것을 확인 할 수 있다.

4. 링크 단계 : 완벽한 실행파일을 생성한다. 이 때 필요한 라이브러리를 모두 합친다.

해당 문구

 /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66 -L/usr/i386-redhat-linux/lib /tmp/ccs3N70j.o -lgcc -lc -lgcc /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/crtend.o /usr/lib/crtn.o


: 오브젝트 파일과 라이브러리 오브젝트를 전부 합쳐서 하나의 실행파일로 만든다.



(a.out 파일 확인)




그렇다면 a.out 파일을 확인해보겠다.




(a.out 바이너리)



파일을 보면 왼쪽에는 메모리 주소인데 파일내용에서 해당 내용을 찾으려면(보통 파일구조 그대로 메모리로 올라가기 때문에) 대략 뒤 3자리를 참조하면된다. (항상 그런것은 아니다.)
확인해보면 3d0의 위치를 보자 



(3d0 위치)



3d0 위치에 우리가 확인했던 바이너리 문자를 볼 수 있다.

* 어셈블 언어로 코드를 작성해보고 컴파일 해보자!
Hellow World 를 출력하는 실행파일을 만들것이다. :)
nasm을 이용할 것이다! 그러기위해 .asm 확장자로 작성한다.



(sample.asm 파일 작성)




(sample.asm 내용)



컴파일 과정에서 어셈블 언어로 바꾸는 과정까지 우리가 직접 한 셈이다.
그러니 그 후 나머지 작업만 해주면 된다.

먼저 오브젝트 파일을 생성해야한다.(바이너리로 바꿔준 파일)
nasm을 이용하여 -f옵션 파일 타입 elf 로 명시한 후 sample.asm을 입력한다.



(sample.o 파일 생성)



그 후 우리가 printf 함수를 사용했으므로 이 함수의 라이브러리를 연결해주어야한다.
바로 링크단계이다.
여기서는 간단하게 static으로 구현해 볼것이다.



(링크 작업)



링크 작업이 끝나면 실행파일이 만들어지게 된다.



(실행파일)



실행 파일이 만들어진 것을 확인 할 수 있고
실행되는 것 또한 확인 할 수 있었다.


+ Recent posts