2016 IGRUS Hack Festival
대회일자 : 5월 21일 ~ 5월 22일
공동제작자 : 임준수, 김정현, 연준모, 곽진우, 조은희, 최정무
템플릿 출처 : http://blog.naver.com/PostThumbnailView.nhn?blogId=metalpan13&logNo=40209691660&categoryNo=46&parentCategoryNo=&from=postList
2016 IGRUS Hack Festival
대회일자 : 5월 21일 ~ 5월 22일
공동제작자 : 임준수, 김정현, 연준모, 곽진우, 조은희, 최정무
템플릿 출처 : http://blog.naver.com/PostThumbnailView.nhn?blogId=metalpan13&logNo=40209691660&categoryNo=46&parentCategoryNo=&from=postList
왜 프로그래머가 가독성을 향상시키는 수련을 평생 해야 하는지를 알려준다. 단지 상투적인 이유만 들먹이는 게 아니다. 좋은 가독성은 프로그래머를 프로로 만들어주고, 큰 기쁨을 주며, 성장할 기회를 준다고 역설한다. 가독성을 향상시키려면 눈에 보이는 것들부터 신경을 써야 하며, 코드 자체가 프로그램을 설명해야 하며, 흐름을 단순화하고 주석을 잘 쓰고 퇴고해야 한다는 간단한 원칙부터 지켜나가야 한다.
21. level4
문제 분석
서비스 파일 내용을 분석해보면 다음과 같다.
service finger {
disable =no // 서비스를 허용 한다.
flage = REUSE //소켓의 포트를 재사용한다.
sock_type =stream //TCP 를 이용하여 통신한다.
wait =no //다수의 사용자가 서비스를 이용하게 한다.
user = level5 //서비스의 실행권한이다.
server = /home/level4/tmp/backdoor
//서비스가 실행될때 실행하는 프로그램이다.
log_on_failure +=USERID
}
22. level4
풀이 제시
finger 명령어가 xinetd에 backdoor 형태로 등록되어있고
소켓을 쓰는걸로 보아 network 요청을 할때
server 에 등록된 프로그램이 실행되는것 같다.
finger @[network ip] 입력
server 값에 등록된
/home/level4/tmp/backdoor가
실행
27. level5
풀이 제시
레이스 컨디션 문제를 이용해 풀어보려 한다.
리눅스 같은 시스템은 프로그램을 동시에 실행하는 것을 허용 하기 때문에
이를 이용해 풀이 계획을 짜봤다.
tmp 파일 생성
같은이름의
심볼릭 파일(바로가기)
생성
내용물 작성
tmp 파일 삭제
level5
심볼릭 파일
조회(cat)
28. level5
풀이 제시
해당 프로그램을 여러번 실행하는 프로그램(executelevel5)를 작성
심볼릭 파일을 여러번 생성하는 프로그램 작성 (createsymlink)
그리고 내용물을 볼 파일 (whatis) 생성을 했다.
49. level9
풀이 제시
buf에 fgets로 문자 16자 (40 - 24) 를 넣고
go를 입력 후 엔터를 치면 다음과 같은
결과가 나올 것이다.
buf [ebp - 40]
AAAA
BBBB
CCCC
DDDD
buf2 [ebp - 24]
gon0
ebp
return value
50. level9
풀이 제시
실험한 결과를 눈으로 확인했더니 gon 가 들어간 것을 확인할 수 있었고
if문안의 statement를 실행한 것을 볼 수 있었다.
63. level11
풀이 제시
스택의 실행 권한이 있으므로
A*264+return address(4 byte)+(nop shellcode)를 넣으면.
스택 안에서 쉘 코드가 실행이 될 것 이다.
str [ebp - 264]
AAAAAA.....
ebp
AAAA
return value
new return value
0xbfffeXXX
nop + shell code
.....
nop(0x90) ....
nop(0x90) ....
nop(0x90) ....
nop(0x90) ....
shell code start
64. level11
풀이 결과
스택의 주소가 계속 바뀌므로 여러번 시도를 해서
(return address 는 bfffeXXX대의 아무 주소)
결국에는 shell을 획득 할 수 있었다.
71. level13
문제 분석
attackme를 직접 디스어셈블리를 하여 i 가 [ebp - 12] 이고,
str이 [ebp - 1048] 이므로 buf가 i 보다 낮은 주소라는 것을 알았다.
72. level13
풀이 제시
i의 위치를 제대로 파악할 수 있으므로(1048 - 12 = 1036 다음 4자리)
1036자 부터는 0x1234567을 넣어 if문을 우회할 수 있을 것이다.
buf [ebp - 1048]
(1036자)
i [ebp - 12]
x67x45x34x12
다음 8자
ebp (4 byte)
return value
new return value
0xbfffeXXX
nop + shell code
.....
nop(0x90) ....
nop(0x90) ....
nop(0x90) ....
nop(0x90) ....
shell code start
98. level17
느낀점
이번 문제는 지난번 처럼 버퍼 주소를 무작위로 때려 맞추는 것보다
확실하고 정확하게 쉘을 얻는 주소값을 삽입 할 수 있는 방법을 알려준 문제이다.
99. level18
문제 분석
이번 소스코드는 조금 복잡하다. 천천히 본다면 별로 어렵지 않은 문제일 것이다.
먼저 사용하는 변수들은 총 5개이고 string 변수가 맨 앞에 정의되어 있으므로
string 변수로 값을 수정할 수 없다...
100. level18
문제 분석
문제는 바로 이곳인데 천천히 살펴보면 다음과 같다.
fds를 초기화하고 stdin을 fds변수에 넣었고 stdin을 사용하여 키보드 입력값을 받는다.
fds가 stdin인지 확인하고 x 변수에 입력값을 1byte에 저장한다.
입력 값에 따라 switch문이 실행된다.
check 가 deadbeef 이면 쉘을 획득한다.
키보드에서 입력을 받아.
string 변수에 1byte씩 저장하거나
필터링을 한다.
102. level18
문제 분석
처음 부터 0x08을 x에 저장하면 count가 마이너스로 흘러감으로 그게 무엇을
의미하는지 예제 코드를 짜보았다 결과는 다음과 같다.
count가 음의 값이면 스택의 윗 부분을 건들 수 있다..
103. level18
문제 분석
각 중요 변수의 위치와 어떤 어셈코드가 c코드로 변환되었는지 분석한 결과는 다음과 같다.
check는 [ebp-124]를 가리킴
104. level18
문제 분석
각 중요 변수의 위치와 어떤 어셈코드가 c코드로 변환되었는지 분석한 결과는 다음과 같다.
x 는 [ebp-128]을 가리킴
105. level18
문제 분석
각 중요 변수의 위치와 어떤 어셈코드가 c코드로 변환되었는지 분석한 결과는 다음과 같다.
count 는 [ebp-132]를 가리킴
106. level18
문제 분석
각 중요 변수의 위치와 어떤 어셈코드가 c코드로 변환되었는지 분석한 결과는 다음과 같다.
string의 위치는 [ebp-120]를 가리킴
107. level18
풀이 제시
string [ebp - 120] check [ebp - 124] 의 위치 차이가 -4 이고
아까 봤던 array의 마이너스 주소참조 규칙을 이용하여 풀면 된다.
&check &string
0xef 0xbe 0xad 0xde
0x08을 4번 입력
xefxbexadxde를입력
결론 : x08x08x08x08xefxbexadxde를입력
113. level20
문제 분석
이번 문제는 아예 bleh 변수의 길이만큼 제한 시켜버렸다.
하지만, printf문을 봣을 때 포맷 스트링 버그를 써서
쉘코드를 실행 시킬 수 있을것 같다.
114. level20
문제 분석
포맷 스트링 버그는 %x 나 %d 처럼 포맷 스트링을 이용하여
스택의 정보를 이끌어 낼 수 있다. 그걸 이용해 bleh 의 위치를 얻어보자
일단 hint를 조금 수정하여 컴파일 해 보았다. 전역변수를 빼면 똑같은 코드이다.
115. level20
문제 분석
포맷스트링을 하나씩 넣어서 특정한 값을 얻을 수 있었는데 25207825 값은 아스키 코드로 "%x %"이므로
bleh 값이 들어간 것을 확인했다.
116. level20
문제 분석
그 이유는 어셈블리어 안에서의 함수의 구조 때문이다.
이 성질을 이용해 포맷 스트링을 이용해 값을 넣어보자.
printf("%x %x %x %x",arg1,arg2,arg3,arg4);
printf를 호출하기 전
스택 frame
address of bleh[80]
arg1 (0x0000004f)
arg2 (0x4212ecc0)
arg3 (0x4207a750)
arg4 (bleh)
117. level20
문제 분석
만약 target 주소값을 넣고 조회 싶으면 이렇게 하면된다.
printf("x0cx95x04x08%x %x %x %x",arg1,arg2,arg3,arg4);
printf를 호출하기 전
스택 frame
address of bleh[80]
arg1 (0x0000004f)
arg2 (0x4212ecc0)
arg3 (0x4207a750)
arg4 (&target)
118. level20
문제 분석
target의 값을 변경하고 싶으면 %n 을 쓴다.
(해당 arg가 int* 를받고 해당주소에 지금까지 출력한 값을 저장한다.)
printf("x0cx95x04x08%x %x %x %n",arg1,arg2,arg3,arg4);
printf를 호출하기 전
스택 frame
address of bleh[80]
arg1 (0x0000004f)
arg2 (0x4212ecc0)
arg3 (0x4207a750)
arg4 (&target)
119. level20
문제 분석
특정 값을 입력하고 싶으면 다음과 같은 규칙이 필요하다
첫번째 주소값 에 B를 입력하고싶다면 %x%Ax%4$n --> B = r + A + 8 (단 A > 8)
printf를 호출하기 전
스택 frame
address of bleh[80]
arg1 (0x0000004f)
arg2 (0x4212ecc0)
arg3 (0x4207a750)
arg4 (&target)
특정한 값 0xdf 를 입력하고 싶다면 0xdf = 초기값(attackme 는 e 이다) + A + 8
즉 , A = 0xdf - 0xe + 8= 217
120. level20
문제 분석
두 번째 주소값부터 값을 넣는것은 첫번째 값을 넣는 것 보다 쉽다.
printf를 호출하기 전
스택 frame
address of bleh[80]
arg1 (0x0000004f)
arg2 (0x4212ecc0)
arg3 (0x4207a750)
arg4 (&target)
arg5(&target+1)
넣고 싶은 값이 C 라면
C = 이전값 + D
C 보다 이전값이 더 크다면
C*0x100 = 이전값 + D
다음은 target주소에 0x10bf 를 넣는 방법이다.
[1번째 byte 주소값][2번째 byte 주소값]%x%[0bxf-0xa(다시 계산해준 초기
값)+8]x%4$n%[0x110-0xbf]x%5$n
110이들어갔지만 다음 주소로 덮어써 지울 수 있다.
121. level20
풀이 제시
level20 문제의 관건은 어느 주소값에 쉘코드를 넣어야 하느냐이다.
하지만 우리는 특정 주소 값에다 특정 값만 삽입 해봤지 쉘코드를 삽입을
한 적이 없다.
122. level20
풀이 제시
소멸자 섹션을 이용해 쉘코드의 주소값을 입력하여
프로그램이 끝날 때 쯤 쉘코드를 호출해보자
그렇다면 다음과 같은 공격 설계가 된다.
소멸자 section
0xffffffff nop
+
shell code의 주소
삽입
0x00000000
nop + shellcode
x90x90x90x90
shellcode