레지스터, 주기억장치, 보조기억장치. 레지스터는 cpu의 일부. cpu의 동작속도와 동기화돼서 상당히 빠르게 작동. 주기억장치는 cpu에 직접 접근이 가능한 메모리 보조기억장치 cpu에 직접읽는다
메모리의 위치와 메모리 주소 개념 각각의 주소에는 8비트의 데이터를 저장할수있도록 되어있다. 각각의 주소는 특정 메모리 위치에 대한 고유 식별자
컴퓨터가 메모리 위치를 식별하는 과정 주소지정
메모리 주소가 8비트라고 했을때. 중간에 00000100 한 6개의 공간을 가지고있을떄 처음에는 비어있다. 1011011이라는 데이터를 00000111 주소에 넣는다.
주소 메모리
00000111 1011011
어떠한 식으로 메모리에 여러가지 값들이 저장되나
하나는 데이터영역이 필요하다.
프로그램에 필요한 전체적으로 사용되는 여러가지 변수들
프로그램에 사용되는 전역변수들이있고 이를 사용하기위해 할당되는것.
이러한 데이터영역은 프로그램의 시작과 동시에 할당.
데이터 영역에 대한 다양한 전역변수 같은 데이터를 저장.
프로그램이 종료되면 소멸된다.
스택 영역 함수 변수 저장, 함수 호출시 생성, 함수 완료시 소멸
메모리 구조 힙영역- 필요에 의해 동적으로 메모리 할당
메모리 구조 모습
STACK
HEAP
DATA
TEXT 위로올라간다~
스택영역은 높은주소에서 낮은주소로. 꺼꾸로 자라난다.
Stack 영역에는 Ret(Return Address), SFP(Stack Pointer), 변수1,2 메모리 주소가 높은 것 부터 낮은 것 순서대로 변수1과 2가 할당
data 영역에서는
메모리의 낮은주소부터. 변수 3 4 5 6
변수들이 어떤 방식으로 메모리에 할당되는지보자
Main() {
int a=1;
int b=2;
int c=3;
int d=4;
}
ini i=77;
변수의 메모리주소: 0xbffffb44 변수의크기: 4byte 변수에 저장된 값: 77
우리가 a,b,c,d, 순서로 변수를 지정했따. 그런데 나중에들어온변수 즉 d가 가장 낮은 주소가 할당되어있다는 것을 눈여겨 봐야한다.
변수1에 임의로 4byte보다 큰 값을 입력 -> 할당되지 않은 영역 사용 가능
다른 영역까지사용하게 되는 취약점 존재
버퍼 오버플로
취약한 특정 함수 사용, 메모리 취약 부분 발견 하지만 언제 발승하냐. 사용자 입력 요구시. 이미 정해져있는 데이터를입력으로 받는 것이아니라 사용자가 임의의 값을 입력할수잇또록 해놓은 부분이 있을때
사용자가 10글자 사용하겠지 예상하고 프로그래밍 짰는데 20글자써버린다. 즉 스택과 힙 프로그램이 진행되면서 자라날수있는 공간에 주로 공격대상
stack 오버플로우.
지역변수,인자, 그다음에 함수가 종료된뒤에 돌아가서 return값.
특히 return값.
입력값 조작, 관리자 권한 획득, 프로그램조작
힙 오버플로
malloc이나 calloc같은 함수를 사용해서 프로그래머가 직접적으로 공간에 여러가지 데이터를 할당하게된다. 버퍼 오버플로 이해
Main() { cchar name char school printf("학교가 어딘가요 gets(name) printf(대학인가요) gets(SCHOOL) printf("제가 다니는 학교는 %s)
여기서 중요한건 gets name , gets school 키보드로 부터 문자열을 입력받아서 지정된 버퍼에 저장하는 함수가된다 . 문제는 비정상적 값 입력 여러 개의 변수 선언 30개를 name 배열에 넣음 그럼 버퍼오버 플로 발생
패스워드를 입력 받는데 그러한 인증 없이 패스워드 인증을 통과할 수 있는 버퍼오버플로우와 관련된 실습
두번쨰로는 악성코드 실행할수있는것
main(){
int auth = 0;
char passwrd[20];
printf("패스워드:");
gets(passwd);
if(strcmp(passwd, "passkey") == 0)
auth = 1;
if(auth)
printf("인증 성공!\n");
else
printf("인증 실패!\n");
}
strcmp라는 함수 사용해서 사용자가 입력한 패ㅡ워드와 이 프로그램에서 사전에 저장해놓은 지정해놓은 passkey라는 패스워드 값을 비교한다.
그리고 같을 경우에는 auth변수에 1을 할당= 즉 통과됐다. 그 뒤에 auth 값에 따라서 정상적으로 사용자가 passkey를 입력했다고하면, 값이 1이기 때문에 printf, 즉 인증 성공을 화면에 보여준다. 아니면 인증 실패
gcc -o bof_test bof_test.c
만약에 ./bof_test 패스워드 :test 인증실패!
라고 입력했을때 프로그램 플로우에따라서 passkey랑 다른값이나옴
로 저장했다. 패스워드가 나왔을때 프로그래머가 미리 지정해놓은 패스워드:passkey 입력했을때 인증 성공메세지가 뜬다.
만약에 1을20개넣었을때는? 버퍼 오버플로 문제떄문에 이러한게 발생한다. 잘못된 패스워드 입력했지만 인증 통과
auth값이 참 거짓 여부 판단. 그러나 auth가 int값이기 때문에 0이외에 다른 값이 들어갈 수도있다.
또한 if else statement에서는 auth값이 1이냐 0이냐에따라서 인증성공과 통과를 결정
그래서 0제외 다른값이 들어가면- 인증이 통과된다는 뜻
실습2
void bof_trouble() {
int a = 107;
char buffer_array[128];
gets(buffer_array);
}
<buffer array > < a > < return address>
NOP NOP<exploit> 0xN 107 0x Return
return주소 -> bof trouble 호출 함수
넘어가는 주소를 return주소 초기 메모리 구조가 설정
buffer array에 hello world! 입력했다치면
128캐릭터보다 작으니까 buffer_Array에 일부분만 채워짐
근데 만약에 NOP NOP 0xN 넣었다치면
bof 함수가 실행뒤에 어디로? return address에 0xN exploit 코드가 실행될수있는 그주 소로 점프가되고 실제적으로 exploit코드가 실행이되게된다.