문제분석 & 풀이level18과는 다르게 간단한 코드 문제다. buf[20]가 선언됐고 gets()로 입력값을 받아서 buf에 저장한다. 간단하게 페이로드 구성해서 BOF하는 문제인 것 같다. 페이로드 구성을 위해 attackme를 tmp로 복사하여 GDB로 분석했다. 분석해보니 0x28(40)바이트의 공간을 할당하고 있다. [ebp-40]이 fgets()로 입력한 데이터를 저장하는 공간인 것 같다. c 코드에서는 buf가 20바이트 할당됐지만, 실제 스택에서는 40바이트의 공간이 할당됐다. 어쨌든 40바이트의 공간이 할당됐고 스택의 구조를 만들어보면 다음과 같다. buf와 SFP 사이에 20바이트 만큼의 더미가 존재한다. 페이로드를 구성해보자. (python -c 'print "A"*44+"[셸코드 주..
문제분석 & 풀이 코드가 너무 길기 때문에 핵심만 분석하겠다. 1) string[], check, x, count 등의 변수 선언 2) count가 100 이상이면 공격의심 문구를 출력check == 0xdeadbeef면 shellout()을 실행하고 level19 권한의 셸을 실행한다. 3) 사용자에게 입력값을 1바이트씩 받고 변수 x에 저장if) x의 값이 0x08이면 count--를 진행else) x의 값이 조건 이외의 값이면 string[count]에 x 값을 저장하고 count++ level19의 권한을 얻기 위해서는 check를 0xdeadbeef로 만들어야한다. 그러나 [사진]에서 알 수 있듯이 check 변수의 위치가 입력값을 저장하는 string보다 스택 하단에 위치하기 때문에 str..
문제분석 & 풀이코드 분석1. printit() : 출력문 출력2. crap, *call, buf[] 선언3. call에 printit()의 주소를 넣는다. 4. fgets()로 사용자에게 48바이트만큼 입력값을 받는다.5. setreuid()로 level18의 권한으로 변경6. call()을 실행함으로써 printit() 실행 이전 문제와 유사한 코드이다. 하지만 셸을 실행하는 함수인 shell()이 존재하지 않는다. 따라서 level16과 같은 방식으로는 문제를 해결 할 수 없다. 그렇다면 어떻게 해결 할 수 있을까? RTL 공격기법을 이용하면 해결 할 수 있다. RTL을 활용하기 위해서는 system(), "/bin/sh" 등의 주소를 구해야하는 번거로움이 있다. 더 쉽게 풀기 위해서 번거로운 작업..
문제분석 & 풀이코드 분석1. shell() : level17의 권한으로 셸 실행2. printit() : 출력문 출력3. crap, *call, buf[]를 선언했으며 call에는 printit()의 주소를 넣어주고있다.4. fgets()을 통해 48바이트만큼 사용자에게 입력값을 받는다.5. call()을 호출하여 printit()를 실행한다. call에 printit()의 주소를 저장하고 call()을 호출하여 printit()을 실행하고 있다. 그렇다면 call에 저장된 함수의 주소를 printit() → shell()로 바꿔줄 수 있다면, printit()이 아닌 shell()을 실행하여 level17의 셸을 얻어낼 수 있다. 어떻게 call에 저장된 주소값을 바꿀 수 있을까? call의 위치가 ..
문제분석 & 풀이코드 분석1. crap, *check, buf[]를 선언했다.2. fgets()를 이용하여 사용자에게 45바이트를 입력받는다.3. (*check == 0xdeadbeef) 인 경우에 level16의 셸을 얻는다. 이전 문제와 비교하면 1가지가 달라졌다. level14에서는 check 변수가 int 타입 변수였지만, 이번에는 포인터 변수로 선언됐다. 무슨 차이인지 짧게 설명하도록하겠다. [그림]은 level14 때 사용한 attackme의 스택 그림이다. check 변수가 int형이고 check==0xdeadbeef 여야 한다. 따라서 노란색 박스 영역에 0xdeadbeef 값이 들어가야 level14를 클리어 할 수 있었다. 그러나 이번 문제는 check 변수가 포인터 변수이다. 따라서 ..
문제분석 & 풀이코드 분석1. crap, check, buf[] 를 선언2. fgets()를 통해 buf에 45바이트의 입력값을 받는다.3. check 변수 값이 "0xdeadbeef" 이면 level15의 셸을 얻어낼 수 있다. buf의 20바이트를 넘어선 45바이트를 입력 받고 있음으로 버퍼오버플로우가 발생할 수 있다. 다만, check 변수를 통해 셸권한을 얻어낼 수 있음으로 check의 값을 "0xdeadbeef"로 설정하도록 페이로드를 완성해 BOF를 시도하는 것이 문제의 핵심이 될 것이다. 코드를 보면 buf 상단에 check가 위치하는 것을 알 수 있다. 하지만 그 사이에 dummy가 얼마나 있을지 모르기 때문에 GDB로 직접 디버깅해서 확인해야한다. attackme를 tmp 폴더로 복사했다..