2016 IGRUS Hack Festival
대회일자 : 5월 21일 ~ 5월 22일
공동제작자 : 임준수, 김정현, 연준모, 곽진우, 조은희, 최정무
템플릿 출처 : http://blog.naver.com/PostThumbnailView.nhn?blogId=metalpan13&logNo=40209691660&categoryNo=46&parentCategoryNo=&from=postList
PROB 2 Exp.
쿠키값을 조작할 수 있는가, 간단한 php코드를 읽을 수 있는가
지수 표현법을 알고 있는가
13.
PROB 2 Solv.
Solve함수를 호출하려면 쿠키의 값이 4자리보다 작으면서 값이 9999보다
커야 한다. 툴 또는 자바스크립트로 쿠키의 값을 바꾸어 주면 된다.
조건을 만족시키기 위해서는 1e5와 같은 지수 표기법을 사용해야 한다.
1e5라는 표기는 1*10^5와 같은 표기이다.
PROB 5 Exp.
JavaScript 난독화 툴을 이용한 난독화 시 나타나는 현상과 이를
원래의 코드로 되돌리는 방법에 대한 지식이 있는지 확인.
31.
PROB 5 Solv.
문제페이지에서는 아무것도 출력하지 않다가 키보드 입력 시 입력한 값을
화면에 연속해서 출력한다.
문제 화면의 html 소스를 보면 다음과 같이 읽기 힘들게 난독화가 되어 있다.
몇몇 키워드가 보이기는 하지만 무슨 의미인지 정확히 알기 힘들다.
32.
PROB 5 Solv.
구글에서JavaScript 언패킹 사이트를 찾아
난독화되어 있는 부분을 넣고 언패킹 하면
다음 스크린샷과 같이 본래의 JavaScript
코드가 나온다.
살펴보면 키보드 입력을 통해 화면에 출력
했던 문자열을 홀수 번째에 있는 문자만 비교
하여 “IG1253”과 같으면 solve()함수를 실행
하도록 되어 있다. 문제 화면으로 돌아가
“I G 1 2 5 3”을 입력하면
문제 해결 페이지로 넘어가 다음과 같은
Alert 창을 볼 수 있다.
PROB 6 Solv.
링크를누르면 Shark.pcapng 파일이 다운받아지고
해당 파일은 WireShark로 열 수 있다.
파일을 열면 패킷들이 아주 많은데 그 중 파일을 다운받은 흔적을 찾아야 한다.
WireShark의 Export object 기능을 사용해 파일들을 저장하면 십여 개의
파일들이 저장된다. 그 중 Broken_By_Shark라는 이름의 파일을 발견할 수 있다.
36.
PROB 6 Solv.
Broken_By_Shark파일은그냥 열리지 않는데 Hex Editor를 사용해서 파일을
열어보면 파일의 앞부분에 있는 PNG키워드로 해당 파일의 확장자가 PNG임을
유추할 수 있다. 하지만 PNG로 확장자를 고치고 실행해도 깨진 파일이라 뜨는데,
PNG파일의 시그니처를 검색하면 89 50 4E 47 0D 0A 1A 0A임을 알 수 있다.
따라서 해당 파일의 첫 번째 바이트를 89로 고치고 저장 후 실행하면 된다.
PROB 7 Exp.
기본적인php코드를 읽을 수 있는가
MD5에 대한 기본적인 지식이 있는가
문제 풀이를 위해 간단한 코드를 작성할 수 있는가
39.
PROB 7 Solv.
소스가주어지고, 데이터를 입력하고 submit버튼을 누르면 아랫줄에 결과가
나타난다. Flag변수의 값이 AuthKey임을 알려 준다.
소스를 분석해 보면,
입력받은 데이터+flag+”0” 을 하나의 문자열로 만든 뒤
16자리씩 끊어 MD5 해시한 후 그 결과를 이어 붙인다.
40.
PROB 7 Solv.
먼저flag의 길이를 알아내기 위해 data의 길이를 조정해보며 입력해 보면
6자리의 데이터를 입력했을 때 결과값이 64자리로 나오는 것을 알아낼 수 있다.
이는 data+flag+”0”의 값이 16자리를 넘어갔기 때문이고, 데이터가 5자리일 때
합은 16자리가 되는 것이다. 따라서 flag의 길이는 10자리임을 알 수 있다.
또한 6자리를 입력했을 때의 결과값을 복호화해 보면 0임을 알 수 있다.
플래그를 모두 알아내기 위해서는 한 자리씩 늘려가면서 뒷부분을 복호화하면
된다.
41.
PROB 7 Solv.
툴이나웹사이트에서 복호화를 하는 방식으로 하나하나 flag를 알아내다 보면
문제가 발생하는데, 5번째 정도부터 원 문자열이 길기 때문에 레인보우 테이블을
이용하여 복호화하는 방식으로는 flag를 알아낼 수 없다. 따라서 플래그가
될 만한 문자들을 MD5해시한 값이 입력 결과와 같은지 비교하는 방식으로
답을 알아내는 것이 가능하다. 위 코드에서 flag와 hashed값을 바꾸어 가며
모든 플래그를 찾아낼 수 있다.
PROB 9 Exp.
Blindsql injection에 대하여 알고 있는가.
필터링을 우회하여 직접 공격해볼 수 있는가.
48.
PROB 9 Exp.
pw가db에 있는 pw와 일치하면 auth key를 띄운다.
Or, and, substr, mid, ascii, =, 스페이스바, 탭 등을 필터링한다.
소스코드
DB
49.
PROB 9 Solv.
id를admin으로 가져오기 위하여 guest를 concat함수를 이용하여 제외한다.
ascii, or, space가 필터링이 되어 있기 때문에 이를 우회하는 방식을 사용했다.
and, =, mid까지 우회하여 pw를 찾는 sql 삽입문을 작성한다. 이를 이용해 brute
force를 하여 pw를 찾아낸다.
PROB 10 Exp.
리버스엔지니어링 기법을 통해 코드를 분석하고 이를 통해 실행 파일에서
원하는 값을 얻어내는 능력
52.
PROB 10 Solv.
프로그램실행 시 Key를 입력받고
그 Key값을 어떤 값과 비교하여 일치
하지 않으면 이와 같은 문구를 출력
하는 듯 하다.
정확한 Key값을 알아내기 위해
OllyDbg를 이용해 해당 실행파일을
열어 보았다.
해당 코드의 처음
부분이다. 무언가
여러 번 연산을 하고
EBP-C에 위치한 변
수에 저장하고 있는
것을 볼 수 있다.
53.
PROB 10 Solv.
코드의다음 부분이다. cin 함수를 통해 받아온 값을 EBP-18의 장소에
저장하고 그 뒤 EBP-18에 있는 값과 EBP-C에 저장되어 있는 값을 비교
한 뒤 다를 경우 “No…. Try Again!” 구문을 출력하는 포인트로 이동하는 것을
볼 수 있다. 일치할 경우 왠지 EAX에 우리가 입력한 값이 저장되어 있는 EBP-
18에 있는 값을 넣은 뒤 cout 함수를 두 번 실행하고 있다. 아마도 일치 시
출력하는 문자열과 함께 입력 받은 값을 같이 출력하는 듯 하다.
54.
PROB 10 Solv.
정확한Key 값을 얻어내기 위해 마지막으로 EBP-C에 값을 넣기 직전의 EAX값
을 확인해 본 결과 위와 같은 값이 나왔다. 이를 10진수로 고치면 264523이라는
값이 나온다. 이를 파일을 실행하여 입력해 보면
다음 화면과 같이 Auth값을 얻어낼 수 있다.
PROB 11 Exp.
리버스엔지니어링 기법을 통해 코드를 분석하고 특정 부분의 코드를
변조해 원하는 결과를 얻어내는 능력
57.
PROB 11 Solv.
프로그램을실행시켜 보면 많이
본 듯한 게임이 실행된다. 뱀은
방향키로 입력 받은 방향대로 계속
해서 움직이고 먹이를 먹으면 길이
가 한 칸씩 증가한다. 어림잡아 보
아도 먹이 한 개당 100점이 증가
하고 총 500칸이 안 돼 보이므로
50000점은 정상적인 방법으론 불
가능 할 것 같다. 해당 파일을
OllyDbg로 실행해 보았다.
이 파일에선 특정 부분
을 계속해서 반복하고
있으며 반복될 때 마다
뱀이 지워졌다 한 칸
전진한 상태로 다시 그
려지는 것을 확인할 수
있다.
58.
PROB 11 Solv.
그러므로JMP하는 구문을 찾아 BP(Break Point)를 걸어 놓으면 한 번 실행할
때마다 뱀이 한 칸씩 이동하게 된다. 방향키를 조작하며 실행해 뱀이 먹이를 먹
기 직전까지 이동한 후 코드를 분석해 보았다.
다음과 같이 의심스
러운 부분을 찾을 수
있다. 무언가 연산을
행한 뒤 값을 EBP-8
에 넣고 0C350과 비
교하는데 이는 10진
수로 50000이다.
JLE구문은 비교한 값
이 작거나 같으면
점프하는 구문이며 조건이 만족할 시 002D1438에 있는 함수를 실행하는 듯
하다. JLE 구문을 JE로 바꾸면 점수가 50000보다 작아도 Call을 시행하므로
JLE를 JE로 변조한 뒤 프로그램을 실행해 보았다.
59.
PROB 11 Solv.
그러자Score 값이 50000이 넘지 않아도 Auth 값이 밑에 표시되는 것을
확인할 수 있다.
002D1438에 있던 함수는 Auth값을 밑에 출력해 주는 함수였던 듯하다.
PROB 12 Exp.
지역변수buffer와 환경변수 전부를 초기화 시킬 경우 어떻게 다른
사용자의 로그인 쉘에 접근할 수 있는지를 알아보기 위함
62.
PROB 12 Solv.
버퍼의크기가 256이나
마지막 코드 memset 함수를
통해 버퍼를 초기화하고 있다.
그리고 환경변수들도
초기화하고 있어 쉘코드를
버퍼와 환경변수에 넣어
공격할 수 없다. 또, 스택의
주소를 꼭 사용하도록
확인하고 있어 스택에
쉘코드를 넣어 공격해야 된다.
따라서 쉘코드를 넣을 공간을
찾아야 하는데 이 때는
argv[2]를 이용하면 된다.
그러기 위해서 argv[2]의
주소를 구해야 하는데 c파일에
코드 추가해서 argv[2]의
주소를 쉽게 구할 수 있다.
63.
PROB 12 Solv.
printf(“%pn”,argv[2]);
와 같은 코드를 추가하고
컴파일한다.
스택은 들어가는 데이터의
양에 따라 주소값이 계속해서
변하므로 공격할 때와 같이
컴파일한 파일로 공격한다.
그렇게 해서 알아낸 주소값이
0xbffffbfe 이다. 이것이
argv[2]의 주소로 igrus2
권한이 있는 igrus2 파일로
공격한다.
64.
PROB 12 Solv.
알아낸주소값으로 공격하면 성공적으로 igrus2 로그인 쉘에 접근할 수
있게 된다. my-pass 명령어를 통해 auth키를 알아내면
‘1n$tack_make%@rgv2--!’ 임을 알 수 있다.
PROB 13 Exp.
스택을사용하지 못하게 막아 대신 gets 함수의 임시버퍼를 이용하여
다른 사용자의 로그인 쉘에 접근할 수 있는지를 보기 위함
(힌트는 끝나기 3시간 전에 공개함)
67.
PROB 13 Solv.
소스코드를보게 되면 gets
함수로 입력을 받고 있는데
buffer[23]의 값이 ‘xbf’
이라면, 즉 스택의 주소를
이용하면 프로그램이 종료되어
공격할 수 없게 된다. 그래서
RTL 기법이나 gets 임시버퍼를
이용해야 하는데 RTL 기법은
마지막 코드 memset 함수로
초기화시키고 있어 막고 있다.
gets 임시버퍼의 주소를 구하기
위해 igrus3 권한을 가진
파일을 컴파일한다.
68.
PROB 13 Solv.
strace명령어는 프로그램
디버깅하는 명령어로 쉽게
말해서 시스템 콜 함수들이
어떻게 호출되고 있는지를
보여준다.
파란색 사각형으로 둘러싸인
부분이 gets 함수가 호출된
부분이며 빨간색 사각형으로
둘러싸인 부분이 gets
임시버퍼의 주소를 의미한다.
따라서 쉘코드를 넣고 return
address 값을 임시버퍼의 주소로
덮어씌우면 공격에 성공할
것이다.
69.
PROB 13 Solv.
gets함수를 이용해 입력받으므로 cat 연산자와 파이프 연산자를
이용하여 buffer overflow를 일으키면 igrus4의 로그인 쉘에 성공적으로
접근할 수 있게 된다.
PROB 14 Solv.
스택의주소를 사용하지 못하게
막고 라이브러리 주소를
이용하게끔 코드가 작성되어져
있다. 이 때는 RTL 기법으로
Return to Library 기법이다.
즉, 라이브러리 함수를 사용하는
기법인데 여기서는 system
함수를 사용할 것이다. 그러기
위해서는 system 함수의 주소와
system 함수 내부에 존재하는
‘/bin/sh’ 라는 문자열이 저장된
공간의 주소를 알아야 한다.
73.
PROB 14 Solv.
디버거를통해 system
함수의 주소를 구할 수
있으므로 디버깅할 수
있도록 컴파일하고 gdb
디버거를 이용해 system
함수와 exit 함수의 주소값을
구한다.
구한 결과 system 함수의
주소는 0x40058ae0 이며,
exit 함수의 주소는
0x400391e0임을 알 수 있다.
74.
PROB 14 Solv.
왼쪽과같이 코드를 작성해
문자열 ‘/bin/sh’의 주소값을
구하도록 한다.
코드 작성 후 컴파일하여
실행하면 ‘/bin/sh’의 주소는
0x400fbff9 임을 알 수 있다.
이 때까지 구한 주소값들을
이용해 공격한다면 성공적으로
igrus6의 로그인 쉘에 접근할 수
있을 것이다.
PROB 15 Solv.
Returnaddress 부분이 argv[3]과
argv[4]를 이용해 덮고 있으며
스택을 이용하되 주소가
0xbfff0000 이면 공격할 수 없게
된다.
역시 버퍼와 환경변수도 초기화
하고 있어 방법은 argv[2]로
해결한다.
78.
PROB 15 Solv.
printf(“%pn”,argv[2]);
코드를 추가하고 컴파일 한다.
스택은 들어간 데이터의 양에 따라
주소가 바뀌는 특징이 있는데
데이터를 스택에 넣으면 주소가
작아진다.
따라서 nop를 엄청나게 많이 넣게
되면 주소가 작아질 것이다.
80000개 정도 넣은 결과 주소가
0xbffec359로 0xbfff0000보다
작아지게 되었다.
그리고 return address 부분은
흰색 사각형을 참고로 xfe, xc3,
x59, xbf 순으로 덮어씌우면
argv[2]의 주소가 들어가게 된다.
79.
PROB 15 Solv.
이렇게알아낸 것들을 이용해 igrus8 권한을 가진 파일로 공격하게 되면
igrus8의 로그인 쉘에 접근할 수 있게 된다.