목록문제풀이 (39)
ii4gsp

힌트파일을 보면 level14문제에서 보았던 check변수를 포인터로 바뀐것을 알 수 있다. 포인터 변수는 메모리의 주소 값을 저장하는 변수이기 때문에 check변수에 들어가는 값은 메모리 주소의 값이 저장된다. - 0xffffffc8은 ebp-56이다. - 0xfffffff0은 ebp-16이다. 따라서 buf에서 *check까지의 거리는 56 - 16 = 40 40byte라는 빈공간을 채워줘야 할 것이다. - 0xdeadbeef와 *check 포인터가 값을 비교한다. 메모리 상에서 0xdeadbeef의 주소를 알아내 *check의 주소를 0xdeadbeef의 주소로 덮어 씌우면 쉘이 실행될 것이다. 0x080484b2가 0xdeadbeef의 메모리 상의 주소이다. 이제 페이로드를 작성할 수 있을 것이다..

힌트를 보면 gets()함수가 아닌 fgets()함수를 써서 45byte만큼의 입력만 받아 ret변조를 불가능하게 만들어뒀다. check의 값을 0xdeadbeef로 변조를해서 쉘을 실행시켜야한다. attackme를 tmp에 복사하고 gdb로 분석을 해보자 에서 0x38만큼 할당해주었다. 0x38은 10진수로 56byte이다. crap[4byte] + check[4byte] + buf[20byte] = 28byte 컴파일러가 생성한 dummy는 28byte이다. 에서 0xffffffc8은 2진수로 1100 1000인데 1의 보수를 해주면 0011 0111에서 2의 보수를 구하면 +1이 되니 56이된다. ebp-56 위치 주소를 eax로 옮기는 걸 알 수 있다. 에서 eax를 스택에 올리고 fgets()함..

디버거 프로그램을 탐지하는 함수를 찾아보자 프로그램을 실행하면 "정상"이라는 문자가 출력된다. 올리디버거로 프로그램을 열어 실행하면 "디버깅 당함"이라는 문자가 출력된다. Search for -> All intermodular calls를 클릭하고 IsDebuggerPresent라는 함수가 보인다. 함수이름부터 IsDebuggerPresent이기 때문에 디버거를 탐지한다고 의심하였다. 더블클릭을 하여 IsDebuggerPresnt함수가 실행되는 영역으로 이동해주었다. IsDebuggerPresent함수를 호출하는 부분에서 break를 걸고 실행하면 아무런 문자도 출력이 안된다. EAX레지스터의 값을 확인해보니 0이다. IsDebuggerPresent함수를 호출하고 난 다음의 명령인 CMP ESI, ESP..

올리디버거로 파일을 열어보았지만 파일이 열리지않는다. hxd에디터로 한번 열어보았다. 맨 처음부분 MZ 실행 파일 형식은 DOS에서 .EXE 실행 파일에 사용되는 파일 형식이다. PE파일이라는것을 알 수 있다. 분석을 하려고 밑에 내려보니 Yeah, you did it!.Crackme 라는 성공시 뜨는 문자와 JK3FJZh라는 패스워드로 유추할수있는 문자도 나와있다.

#include int sum(int a, int b) { int result = 0; result = a + b; return result; } int main(int argc, char *argv[]) { int x = 9; int y = 4; int result = sum(x, y); if (result > 10) printf("Good!! Result : %d\n", result); else printf("Bad.. Result : %d\n", result); } 예제 소스코드이다. 소스코드를 컴파일하여 실행해보면 이 소스코드는 else문이 출력되지 않는다. 실행파일을 올리디버거로 열어보겠다. 방법1 올리디버거로 열고 조금 밑에 내려가보면 main()함수가 보인다. CMP DWORD PTR SS:..

HDD를 CD-Rom으로 인식시키기 위해 GetDriveTypeA의 리턴값을 알아야 하는것 같다. GetDriveTypeA의 리턴값을 몰라도 문제는 풀수있다. GetDriveTypeA함수의 리턴값을 알아보자 위의 표는 return값에 따른 drive의 type이다. HDD의 리턴값은 3이고 CD-Rom의 리턴값은 5이다. 첨부파일에 있는 프로그램을 실행시켜보면 오류가 발생하고 꺼지게 된다. 방법1 GetDriveTypeA함수의 리턴값을 알기 위해 GetDriveTypeA함수를 호출한 다음에 Break(F2)를 걸어 주었다. 레지스터의 값을 확인해보면 현재 EAX 값이 3이므로 HDD의 return value는 3이라는 것을 알 수 있다. break를 풀어주고 F8로 한줄씩 실행해보면 ESI레지스터는 IN..

파일 실행을하면 콘솔창의 아주 간단한 프로그램이 실행된다. 키값을 입력하라는 문구가 뜨고 이것이 뜸으로써 임의의 키값을 넣었을때 다음과 같은 문구가 뜬다. 방법 1 올리디버거로 파일을 열어 main()함수를 열어 내려가다 보면 파일 실행시 나오던 문구가 보인다. 좀 더 내려가다보면 stricmp라는 문자열 비교 함수를 볼수있다. 문자열 비교를하고 문자열이 같을때 뜨는 문구와 문자열이 다를때 나타나는 문구가 보인다. 디버거에서 프로그램을 실행하여 임의의 값을 넣어주고 입력한 임의의 값이 어떤값과 비교하는지 알아낼수있다. 방법2 또 다른 방법으론 프로그램의 흐름을 바꿔주는 것이다. main()함수에서 조금 내려보면 다음과 같은 어셈블리 코드를 볼수있다. JNZ는 결과가 0이 아닐 때 점프하므로 결과가 0일때..