본문 바로가기

System Programming/CSAPP Lab

(11)
[Buffer Lab] Level 2, Stack Corruption 이용하여 원하는 assembly code 실행시키기 Level 2의 목표 Level 0, 1에서는 stack corruption을 통해 함수의 return address, 함수의 argument 값을 조작할 수 있었다. 여기서는 machine instruction을 input string으로 입력함으로써, 특정 instruction이 실행되도록 하는 것이 목표이다. 이를 조금 더 구체화해보면, 스택이 아래와 같은 상황이 되어야 한다. getbuf 함수에서 stack corruption을 발생시켜 return address가 우리가 원하는 값이 되도록 해야 한다. 이 때 return address를 이어지는 주소 값으로 한다면, 그 다음 주소로 이동하여 machine instruction들을 수행할 것이다. 그리고 이 machine instruction은 ..
[Buffer Lab] Level 1, Stack Corruption 이용하여 함수 argument 조작하기 Level 1의 목표 Level 1에서는 fizz 함수로 흐름을 우회하되, 여기서 cookie를 함수의 argument로 넘겨준 것과 같은 효과를 주도록 해야 한다. 그래서 if 문으로 들어와 문자열을 출력하는 것이 목표이다. 즉, 함수의 흐름을 바꾸는 것은 Level 0과 같지만, 함수의 argument에 대해 분석해본다는 점에서 다를 것임을 알 수 있다. fizz 함수의 시작 주소 값을 확인한다 시작 주소 값은 0x08048c42 이다. Level 0를 풀었으므로, getbuf 함수에서 stack corruption을 발생시켜 원하는 주소 값으로 jump 하는 방법을 알고 있다. exploit string file만 바꿔준다. 실행 결과, fizz 함수에는 도달하였으나, val==cookie 조건을 ..
[Buffer Lab] Level 0, Stack Corruption 이용하여 함수의 return address 조작하기 Level 0의 목표 bufbomb 프로그램이 실행되면 test() 함수가 호출된다. 이 함수 내에서 다시 getbuf() 함수를 호출하는데, 만약 getbuf() 함수가 정상적으로 종료되면, test() 함수의 if-else 문을 들어와서 이전에 그냥 실행시켰을 때처럼 메시지를 출력하고 프로그램이 종료된다. 여기서 원하는 것은 getbuf() 함수가 return할 때, smoke() 함수가 실행되도록 하는 것이다. getbuf() 함수의 Assembly Code gdb의 disas 명령어로 getbuf 함수의 assembly code를 얻을 수 있다. 일단, getbuf 함수를 호출하는 test() 함수의 15줄에 breakpoint를 걸고 실행시킨다. Return Address는 스택에 저장되어 있다..
[Buffer Lab] 프로젝트 파일 다운로드 및 시작하기, executable 프로그램 실행하기(32/64-bit 환경 호환성 해결) 프로젝트 파일 다운로드 Buffer lab의 프로젝트 파일은 아래 링크에서 다운로드 받을 수 있다. 다운로드 링크: http://csapp.cs.cmu.edu/3e/labs.html CS:APP3e, Bryant and O'Hallaron Lab Assignments This page contains a complete set of turnkey labs for the CS:APP3e text. The labs all share some common features. Each lab is distributed in a self-contained tar file. You will need a CS:APP account to download the code. To untar foo.tar, t csapp.c..
[Bomb Lab] Phase 6, linked list operation의 assembly code Read six numbers 함수 마지막 phase라서 그런지 assembly code 길이가 가장 길다. 풀이 순서대로 일부만 첨부하기로 한다. read_six_numbers 함수에서 유추할 수 있듯이, 사용자 입력으로 6개의 숫자를 넣어본다. 처음으로 분기가 있는 42줄에 breakpoint를 걸어둔다. 폭탄이 터지지 않고 실행을 이어가려면 jump가 일어나야 하고, eax 레지스터 값이 5보다 작거나 같아야 한다. 35줄에서 r13 레지스터 값을 base address로 하여 eax 레지스터에 값을 할당하므로, 이 주소를 찍어보았더니 입력했던 6개의 숫자가 들어있다. 즉, eax 레지스터에는 사용자 입력 1번째 숫자가 들어가고, 다시 1을 빼주므로, 1번째 숫자는 6 이하여야 한다는 결론을 얻는다..
[Bomb Lab] Phase 5, 문자열 조작 연산, gdb 메모리 값 참조 Assembly code of phase_5 첫 번째 분기문: string_length 함수의 return 값 확인 29, 32줄에서 첫 번째 분기문이 있는데, 폭탄이 터지지 않고 실행을 이어가려면 string_length 함수의 return 값이 6이어야 한다. 함수 이름으로부터 유추해보면, 입력한 문자열의 길이가 6인 것이라고 추측해볼 수 있다. 먼저, breakpoint를 29줄에 걸어둔다. 예를 들어, hello world를 입력해보면, eax 레지스터 값이 11이다. hello world 문자열의 길이가 11이므로, string_length 함수는 사용자 입력 문자열의 길이를 return한다고 추측할 수 있다. 이제 다시 길이가 6인 임의의 문자열 helloo를 입력하고 계속 분석하기로 한다. ..
[Bomb Lab] Phase 4, 재귀 함수 호출의 assembly code Assembly Code of phase_4() gdb를 켜고 bomb 실행 파일의 phase_4 함수를 disassemble해보면 다음과 같다. 24줄에 scanf 함수를 호출하는 부분이 보이는데, 이전 phase들의 경험을 토대로 생각해보면 뭔가 사용자 입력을 받는데, 여기서는 레지스터 eax가 2와 같을 때만 실행을 이어가므로 입력의 길이가 2여야 한다는 것을 알 수 있다. 입력은 완료된 뒤의 첫 번째 분기인 34줄에 breakpoint를 걸어본다. 임의로 1 2 3이라는 3개의 숫자를 입력으로 넣었는데, 폭탄이 터지지 않고 34줄까지 실행된다. 이 때의 레지스터 값들을 출력했을 때, 레지스터 eax의 값이 2인 것으로 보아 scanf 함수가 입력 2개가 되면 자동으로 종료되는 것으로 추측해볼 수 ..
[Bomb Lab] Phase 3, Assembly indirect jump Assembly 코드 변환 phase_3을 assembly 코드로 변환해보면, 첫 번째 분기: 입력의 길이 확인 우선 첫 번째 분기가 일어나는 곳인 +32 줄에 breakpoint를 찍어보았다. phase 1, 2는 알아낸 정답을 입력하고, 3은 임의로 4개의 숫자 1 2 3 4를 입력해보았다. 이 때 레지스터 eax 값이 2이고, 그러면 1보다 크기 때문에 34줄은 무사히 건너뛰게 된다. 여기서 스크린샷에 첨부하지는 않았으나 10 20 30의 3가지 숫자를 입력했을 때도 eax의 값이 2였는데, 아마도 최대 2개의 입력을 읽어오는 것 같다. 스택 포인터가 가리키는 지점의 메모리 값을 확인해보면, rsp+8, 12에 각각 1, 2번째 입력 값이 들어 있었다. 두 번째 분기: 1번째 입력 값의 크기 확인 ..