학교 수업듣느라 틈틈이 푼 문제이다.
오랜만이다.!



(문제 화면)


부리부리

이름을 봤을 때 힙영역 취약점이라고 예상했다그리고 확인해보니 힙영역의 취약점을 이용한 문제였다.



(프로그램 실행)



문제를 실행해보면 위와 같이 나온다.
기능은 ADD Chunk를 이용해 데이터를 저장할 수 있는데 3개까지 만들 수 있다.
그리고 unlink를 통해 unlink함수를 구현해 놓았구, modify에서는 
기존의 힙의 데이터를 수정할 수 있게 해놓았다.



(전역변수)



취약하다 생각한 것은 A,B,C라는 전역변수를 만들어 두었고, malloc으로 할당받을 때 
각각 A,B,C에 주소를 저장해 놓는 것이었다

그리고 수정할 때 이 A,B,C에서 값을 가져와서 그 주소에 있는 것을 수정했다.



(unlink 취약점)



바로 이부분인데힙영역의 취약점을 일부러 unlink라는 함수를 만들어놔서 구현해 놓았다현재 버전의 시스템에서는 취약점이 막혔기 때문인 것 같다.


(heap overflow)



일단 기본적으로 힙영역 취약점을 이용하려면 heap overflow가 가능해야한다. ADD 함수에서는 전혀 힙오버플로우가 일어나지 않았고 좌절할 뻔했지만 modify가 있었다.
바로 여기서 수정을 하는데 입력을 0x100 바이트 받는다.
나는 GOT를 오버라이트 해서, A,B,C라는 전역변수에 GOT주소를 적고 싶었다그렇게 되면 수정할 때마다 GOT영역을 0x100바이트 내 맘대로 조작할 수 있기 때문이다.
위에서 말했듯 A,B,C라는 전역변수에 malloc을 저장해 두었고, A,B,C 주소 중 가장 끝의 것 C 주소를 선택했다.
 
이제 3번 청크를 수정하면 GOT영역의 데이터에 나의 데이터가 올라간다.
이제 중요한건 system 함수에 /bin/sh 이라는 문자열을 어떻게 전달할 것인가 이다.
 

나는 아주 기맥힌 방법을 생각해냈다.



(공략)



이 부분에서 idx라는 전역변수에서 값을 꺼내오고 확인한 후 puts를 실행하는 과정인데,
여기서 보면 rax를 초기화 하지 않는다.!
 

여기서puts함수를



(덮어쓸 주소)


위 주소로 덮어쓰고, free함수를 system 함수로 덮어쓰면 바로 rax에 있던 값이 system 함수 인자값으로 들어간다.
그렇다면 나는 idx값에 첫번째 청크 주소값 + 0x10 을 넣을 것이다수정할 때 0x10부터 데이터가 들어가고 나는 첫번째 청크에 /bin/sh + 0x00 을 넣을 것이기 때문이다그렇게 되면 /bin/sh 무자열 주소가 system 함수에 전달되는 것이다.
 
그런데 문제가 있었다. Modify 후 가장 먼저 실행되는 것이 puts함수였다즉 puts 함수를 위 주소로 덮어쓰면 제일 먼저 rax값을 설정하는 그 주소를 실행하지 못한다는 것이다.
, puts 함수가 실행되기 전 다른 함수가 실행되어야하고그 함수에 rax값을 설정하는 주소로 덮어써야한다.
 

나는 modify의 카나리 체크함수를 이용하기로 했다일부러 카나리값을 망치게 하는 주소를 free함수에 넣는다그리고 unlink를 실행해 주어 이 주소로 넘어가고이 때 modify에서 puts 함수와 기타 함수를 덮어쓰면 원하는대로 rax값 설정 후 puts 함수로 넘어간다.



(카나리 망치기)


바로 이 주소를 free 함수로!
 

나의 계획을 정리하면 이렇다.



(공략 정리)




(문제 해결)



Exploit 작성 후 공격 실행 성공한 모습


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

(64/500) backdoor - Enter the matrix  (0) 2017.10.31
(63/500) pwnable.kr - syscall  (2) 2017.10.22
(61/500) NOE.systems - double_input  (0) 2017.09.17
(60/500) pwnable.kr - crypto1  (0) 2017.08.27
(59/500) pwnable.kr - dragon  (0) 2017.08.17


오기로 풀어낸 문제이다.

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

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

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


cmd1 많이 쉬웠던 문제이다!



(cmd1)



문제 화면은 PATH 환경변수를 물어보면서 시작한다.



(문제화면)



접속하면 cmd1이라는 프로그램이 있는데
cmd1의 소스코드 먼저 확인해보자.



(cmd1 소스코드)



소스코드를 보니  PATH를 망가뜨린다. 최상위 디렉토리에 우리가 폴더를 만들수 없으므로
저 경로는 과감히 포기하자!

나의 전략은 내가 쓸수있는 tmp 임시디렉토리로 가서 링크를 생성한다.
flag를 다른 이름으로 링크를 건다. 이유는 필터에서 flag를 필터링하기 때문이다.



(링크 생성)



(링크 확인)



링크 확인후 arg[1] 에 명령을 입력하면된다.
이 때 환경변수가 망가졌으니 절대경로로 입력하면 된다.



(문제 해결)

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

(56/500) pwnable.kr - asm  (0) 2017.07.14
(55/500) pwnable.kr - uaf  (0) 2017.07.12
(53/500) pwnable.kr - blackjack  (0) 2017.07.12
(52/500) pwnable.kr - coin1  (0) 2017.07.12
(51/500) pwnable.kr - shellshock  (0) 2017.07.11


blackjack 문제이다.


(blackjack)



문제 화면은 이렇다.


(문제 화면)



여기서 C코드를 주었다.
하지만 나는 보지않았다.. 그렇게 먼길을 걷기 시작했다...

문제에 접속을 하면 게임을 할 수 있다.



(게임 룰)



의외로 재밌었다.

부자한테 플래그를 주겠다는 거니 돈을 버는게 목적이구만?

파이썬 코드로 확률을 계산하여 풀기로 했다.
카드 배열을 만든 후 하나씩 pop 하는 방식이다.



(확률 계산 함수)



(게임 함수)



실제로 내가 배팅을 50퍼센트에 걸것이니, 확률도 50 이상이면 h (go)를 외치게 하였다.
그런데 자꾸 지는거다.. 와이어 샤크로 확인해보니..



(같은 숫자?)



같은 카드들이 반복적으로 온다
뭐지? 카드 배열 쓰는게 아니었어???

그렇다면 나도 꼼수로 나간다.
같은 수가 반복적으로 오니까 21에 근접하게 반복하는 것이다.
5가 오면 그 다음 카드도 5일 것이니 3번만 h를 해주면 20이 되고 내가 이길 확률이 커지는 것이다.
그래도 가끔 숫자가 바뀌니까 그거 고려해서 승률을 어림잡아 1/5로 잡고 배팅도 1/5 로 주었다.



(블랙잭 핵 코드)



(블랙잭함수)



자! 실행하니 돈이 쌓여간다.



(난 부자!!)



그런데 마지막에 뜬금포로 파산했다고 중단된다. 돈이 이렇게나 많은데...
(프로그램 오류일 것이다. 더 이상 큰 수를 가질 수 없는거 같다.)
와이어샤크로 확인해보니
100만 달라가 넘는 순간부터 이상한 문구가 딸려온다.



(이상한 문구?)



flag에 입력해본다.




(문제 해결!)



* 문제를 다 풀이한 후 다른 사람들의 알고리즘은 어떻게 되나 싶어서(내가 꼼수를 썻기 때문에)
확인해보니 코드의 결함을 이용한 방법이었다...
앞으로는 문제에서 주어진 것들을 잘 확인해봐야겠다.

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

(55/500) pwnable.kr - uaf  (0) 2017.07.12
(54/500) pwnable.kr - cmd1  (0) 2017.07.12
(52/500) pwnable.kr - coin1  (0) 2017.07.12
(51/500) pwnable.kr - shellshock  (0) 2017.07.11
(50/500) pwnable.kr - mistake  (0) 2017.07.10


Coin 1 !!

문제 이해가 늦었다.. ㅜ
Coin 문제이다/


(Coin1)


아래는 문제 화면이다.



(문제화면)



문제에 접속하면 게임이 나온다.


(게임 화면)



아마 이 문제를 이해못했던건 나만... 일수도 있지만..
혹시나 못하신 분들을 위해 저의 시선으로 설명!

1. 가짜 코인을 찾는게 목표!
2. N -> 코인의 개수, C -> 무게를 잴수 있는 기회
3. C가 기회라고는 하지만 C번 무게를 잰 후에 답을 말해야한다.
4. N 이 주어지면 그에 해당하는 인덱스를 지정해주면 그 코인들의 무게를 재서 알려준다.
예를들어
N =6 이다 하면.
0, 1, 2, 3, 4, 5    이렇게 동전이 있는 것이다.

내가 0번 3번 5번 코인을 선택해서 0 3 5   이렇게 입력해서 보내면
0 3 5  코인의 무게를 합해서 알려준다. 요론식으로 해서 가짜 코인을 찾는 것!

아래는 나의 파이썬 코드이다.
나의 생각 그대로 코드로 옮겨두었기에 정리가 산만하다.



(해결 코드)




(해결 코드)



100개의 코인을 모으는 것은 순식간이다.
문제 해결!


(문제 해결)

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

(54/500) pwnable.kr - cmd1  (0) 2017.07.12
(53/500) pwnable.kr - blackjack  (0) 2017.07.12
(51/500) pwnable.kr - shellshock  (0) 2017.07.11
(50/500) pwnable.kr - mistake  (0) 2017.07.10
(49/500) pwnable.kr - leg  (0) 2017.07.10


문제를 풀면서 많은 것을 찾아보고 알게 되어 기쁘다. :)

이번 문제는 shellshock 이다.



(shellshock)


문제 화면은 아래와 같다.



(문제 화면)



문제의 키워드는 shellshock이다.
shellshock를 기사공부할 때 공부했었다.
환경변수를 이용해 명령어를 Injection 시키는 공격이라고 공부를 했는데
직접 해보지는 못했었다.

직접 찾아보면서 더 깊이 이해하게 되었다. :)

먼저 문제 접속하여 파일들을 보자.



(문제 접속)


특이점은 bash가 있다는 것이다.

코드를 보자!


(shellshock.c)



쉘쇼크 소스코드이다.
시스템함수로 bash를 실행시킨다.

쉘쇼크를 검색하면 제일 많이 나오는 것이 아래와 같은 진단코드이다.



(쉘쇼크 진단 코드)



vulnerable이 뜨면 취약한 점이라고 하는데 안뜬다..
취약하지 않은건가??

여기서 많이 찾아보게 되었는데
아주아주아주 정리를 잘해주신 블로그를 발견했다. 쉘쇼크의 원리를 빠삭하게 설명해주셨다.

바로 쉘쇼크의 근간은 Bash가 subshell을 실행시키면서 일으키는 버그이다.

예를 들면 export로 환경변수를 설정해보자.



(환경변수 설정)



위의 attack은 변수로 설정 되었다. Bash에서는 함수로 환경변수를 설정할 수 있다.
하지만 저 위의 attack은 쿼터로 둘러싸인 문자열 변수이다.!
(실행은 안된다!)

하지만! export로 선언한 변수는 subshell에서도 적용이 되는데 이 때 버그가 발생한다.

서브쉘로 bash를 열고 attack 함수를 실행해보자.



(함수 실행)



함수가 실행되었다???
문자열인데????

이건 바로 subshell을 실행시킬 때 환경변수 초기화 작업이 있는데 이 때 문자열 안에 있는 것들을 함수로 인식해 설정해버린다는 것에 있다.
더 흥미진진한 것이 있다.

{ ~~ } ; 추가 명령들
{} 안의 내용이 함수로 설정이 되고 그 다음에 추가명령들을 입력하면 이것들이 실행된다.
함수를 실행시키지 않아도 bash 초기화 작업중에 일어난다.
bash 환경변수 초기화 작업에 환경변수에 있는 내용들을 파싱하는 과정에서 입력값을 체크하지 않는 데 서 발생하는 취약점이다. 즉 여기서 echo attack!!! 을 함수로 설정하고 
/bin/cat ./flag 를 명령어 추가로 던져서 설정해보자.


(환경변수 설정)



그 후 shellshock를 실행시키면 된다. 코드 안에 bash를 실행시켜주니 알아서 읽을 것이다.
게다가 setgid가 설정되어있어 읽을 수 있다.



(문제 해결)


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

(53/500) pwnable.kr - blackjack  (0) 2017.07.12
(52/500) pwnable.kr - coin1  (0) 2017.07.12
(50/500) pwnable.kr - mistake  (0) 2017.07.10
(49/500) pwnable.kr - leg  (0) 2017.07.10
(48/500) pwnable.kr - random  (0) 2017.07.06


이번에 풀어본 문제는 mistake!



(mistake 문제)



아래는 문제화면이다.



(mistake 문제화면)



일단 로그인!
소스코드를 살펴보자



(소스코드)



소스코드를 보니 내가 읽을 수 없는 파일을 읽어서 그 값과 내가 입력한 값을 비교하고 있다.
어떻게 맞추지...

그런데 문제 화면에서 진지하게 생각하지말라고 나와있다. 단순한 실수라고
연산자 우선순위 실수?
아무리봐도 특별한 연산자가 없는거 같은데... 괄호를 잘 뒤져봤다.

?!?!?!?


(이상함 발견)



이상함이 발견되었다.
fd에 들어가는 값이 open 이 아니라 bool 연산값?? password 파일의 fd가 0보다는 클테니...
이 비교는 거짓이 되고 고로 fd에는 0이 들어가게 된다..

fd 0은 표준 입력이다.
즉 내가 입력한 표준 입력과 비교하는 것이다. 오케이!

내가 패스워드로 입력한 값을 xor 연산 해주므로 그 함수를 고대로 복붙해서
내가 입력할 것을 넣어서 비교해본다.



(xor)


내가 A 10개를 입력할 것이므로 xor 하면 @ 10개가 된다. 즉 표준입력으로 @ 10개를 입력하고
패스워드로 A 10개를 입력한다.

exploit을 만들어보자.


(exploit 코드)


그 전전 문제에서 표준입력하는 방법을 배워서 여기서 써먹을 수 있었다.

@10개를 입력한 후, A 10개를 입력해준다.! 구분자는 \n 개행으로 하였다.


(문제 해결)



문제해결!


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

(52/500) pwnable.kr - coin1  (0) 2017.07.12
(51/500) pwnable.kr - shellshock  (0) 2017.07.11
(49/500) pwnable.kr - leg  (0) 2017.07.10
(48/500) pwnable.kr - random  (0) 2017.07.06
(47/500) - pwnable.kr - passcode  (0) 2017.07.06


random 이라는 문제이다!



(random 문제)



문제 화면은 아래와 같다.



(문제)



랜덤함수를 이용한 프로그래밍을 했다니 확인해보자

소스코드!


(소스코드)



음 내가 입력한 값과 랜덤값을 XOR하여 저 값이 되게하는 거니까
키 값은 deadbeef XOR 랜덤값을 한 값을 입력하면 되겠군

근데 랜덤값을 어떻게...
오버플로우 문제인가??

내 Centos에 옮겨서 gdb로 돌려보았다. 반복하면서 돌려보다가 엥?

랜덤값이 항상 0x6b8b4567 이 나오는 것이었다.



(같은값)



확인해보니 rand() 함수만 이용하면 항상 같은 값이 나온다는 거였다.

그래서 seed 주어 난수를 생성하는 것이었다. 여기서 조금 의아했던 것은 과연 이게 문제 사이트 시스템에서도 같은 값일까 였다.

내가 알아낸 값과 deadbeef를 XOR해주면 내가 입력해야할 key값이 나온다.



(key구하기)



그리고 결론은 성공!



(문제 해결)



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

(50/500) pwnable.kr - mistake  (0) 2017.07.10
(49/500) pwnable.kr - leg  (0) 2017.07.10
(47/500) - pwnable.kr - passcode  (0) 2017.07.06
(46/500) - pwnable.kr - flag  (0) 2017.07.05
(45/500) - pwnable.kr - bof  (0) 2017.07.05


passcode 문제다.!

조금 시간이 걸렸다ㅜ
문제의 의도를 파악하는데 시간이 많이 들었다.!

passcode 문제 클릭!



(passcode 문제)



문제화면은 다음과 같다.


(문제)


로그인 프로그램을 만들었는데 어딘가 하자가 있는 모양이다.

소스코드를 확인하자!



(소스코드)



소스코드를 보니 멀쩡해 보인다.
뭘까?

실행해보자!



(로그인)



세그멘테이션 폴트?

이 문제를 알기위해 나는 나의 레드햇 32비트에서 소스코드를 컴파일하여 gdb를 통해 디버깅하였다.
그러던 중 신박한 사실을 알았다.

일단 문제의 원인은 scanf 에 있었다.



(문제의 원인)



바로 int passcode1 이 변수의 passcode1는 변수 주소이다. 그러기에 scanf에 넣을때 앞에 &를 붙여 주소를 표현해주어 그 변수 자리에 입력한 정수를 집어넣는 것이다.

디버깅한 어셈블리로 확인해보자!


(문제의 scanf)



바로 위에 빨간 박스가 문제이다.
원래는 그냥 [%ebp-4] 여야하는데 앞에 PTR이 붙었다. 그래서 ebp-4 위치에 있는 값을 주소로 인식하여 그 값의 주소에다가 그 다음 입력한 정수를 집어 넣으려 하니 segmentation fault가 나는 것이었다.

예를 들어 앞에 입력값 A 100개를 주면 아래와 같은 현상이 일어난다.



(이름으로 A 100개 입력)



그렇게 되면 0x41414141 위치에 입력받은 숫자를 저장하려할 것이고 여기서 에러가 나는 것이다.

여기 까지 왔을 때 문제의 의도를 파악했다.
그렇다면 마지막 0x41414141 대신 내가 원하는 주소값을 넣고
그 다음 숫자값으로 그 주소값에 내가 원하는 값을 넣을 수 있다는 말.!

정리해서 말하면 원하는 위치에 원하는 값을 4바이트 넣을 수 있다는 말이다!
그렇다면 그다음 호출되는 함수의 got를 오버라이트 해서 해결해보겠다!!!


(공격 타겟)



먹잇감이 포착됬다.
fflush이다.
여기다가 login 함수에서 system 함수를 호출하는 부분 (인자구성해주는부분포함해서) 그 쪽부터 시작되게 할 것이다.

그 위치를 파악하기 위해 objdump로 확인해보자!



(objdump)




(login 함수)



login 함수의 0x80485e3 위치부터 실행하면 비밀번호까지 얻을 수 있다. 고로 우리는 숫자 값에0x80485e3을 넣을 것이다. 

이제 fflush got 위치 찾기이다.
readelf 를 이용하여 파악해보자!



(3번째 위치)



바로 저게 got 영역에 들어있는 놈들인데 fflush가 3번째에 있다. 위치로는 got 시작영역부터 0x10 큰 위치가 fflush 위치가 된다.

그렇다면 fflush 위치는?


(GOT주소)



GOT 주소는 0x08049ff4 이므로 0x10 큰 0x0804A004 가 fflush 주소가 된다.

입력할 숫자 0x80485e3이 16진수이므로 10진수로 입력해야한다.
%d 가 10진수 표현이므로!




(10진수 표현)



이제 끝이다. 공격!




(공격)



이제 숫자를 입력한다!




(공격 성공)


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

(49/500) pwnable.kr - leg  (0) 2017.07.10
(48/500) pwnable.kr - random  (0) 2017.07.06
(46/500) - pwnable.kr - flag  (0) 2017.07.05
(45/500) - pwnable.kr - bof  (0) 2017.07.05
(44/500) - pwnable.kr - collision  (0) 2017.07.05



bof 문제이다!
bof 원정대의 실력을 꺼낼때가 됬다!

귀여운 너구리 클릭


(bof 문제)


문제화면이다.


(문제 화면)



remote bof? 
nc 로 접속하여 풀게 되어있다.
일단 취약한 프로그램을 한번 확인해보자.

소스 확인!


(소스코드)



소스코드를 보니 func 함수의 인자를 덮어 쓰면 될것 같다.

메모리에서 한번더 확인해보기 위하여 gdb에서 확인!



(메모리 상태)



입력으로 A를 여러개 주었을 때이다.
보면 위에 414141~~ 이 보이고 아래에 func 인자로 넘겨진 deadbeef가 보인다.
여기까지 덮어쓰면 되므로 일단 A 52개를 넣어보자!



(A 52개)


A 52개를 넣으니 딱 deadbeef 전까지 A가 채워졌다. 마지막은 Null 때문에 00이 덮여저있다.
여기에 이제 원하는 코드 를 넣으면 되니 이제 연결을 해보자!



(nc 연결)


전 문제 풀던 쉘에서 localhost로 바로 연결했다.

음! 이걸로 되겠군!

이제 표준입력으로 넘겨서 nc 로컬 연결할 것이다.



(공격!)


계획한대로 A 52개와 0xcafebabe 를 넣어준다. (엔디안 고려해서 뒤집어서 넣어준다.)



(성공!)



bof의 uid를 얻은 쉘을 획득했다.!




(문제 해결!)

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

(47/500) - pwnable.kr - passcode  (0) 2017.07.06
(46/500) - pwnable.kr - flag  (0) 2017.07.05
(44/500) - pwnable.kr - collision  (0) 2017.07.05
(43/500) - pwnable.kr - fd  (0) 2017.07.05
(42/500) - Lena's Tutorial 01  (0) 2017.07.05

+ Recent posts