#About


[그림 1] - evil_wizard.c 소스 코드 확인




#Solution


해당 문제는 GOT overwritng을 통한 ROP 기법을 이용하여 셸을 획득 해야하며 이에 필요한 ppr 가젯을 하나의 함수로 구현해두어 제공함을 확인할 수 있다


setreuid와 setregid도 주어졌겠다 남은 일은 system("/bin/sh")를 실행 시키는 일만 남았으며 간단히 설명하면 다음과 같다


strcpy( printf@got+0 | system[0] );

strcpy( printf@got+1 | system[1] );

strcpy( printf@got+2 | system[2] );

strcpy( printf@got+3 | system[3] );

printf("/bin/sh");


위 과정은 printf 함수의 got 영역을 system 함수의 주소로 바꿈으로써 최종적으로 printf를 실행할 때, system 함수가 실행되게끔 하는 것이다


이에 필요한 가젯들은 strcpy@plt, printf@plt, printf@got, ppr, system, /bin/sh의 주소가 되며 아래의 과정을 통해 구해주었다


[그림 2] - strcpy@plt 주소


[그림 3] - printf@plt 주소


[그림 4] - printf@got 주소


[그림 5] - ppr 주소 


[그림 6] - system 함수 주소


[그림 7] - shell.c 소스 코드 확인


[그림 8] - system 함수 내부 문자열 /bin/sh의 주소


페이로드 작성에 필요한 가젯들을 모두 모았고, 페이로드를 구상해보면 아래와 같아지며 RTL Chaining Calls와 기법이 거의 유사한 것을 확인할 수 있다


| dummy (268) +

strcpy@plt | ppr | printf@got+0 | system[0] | +

strcpy@plt | ppr | printf@got+1 | system[1] | +

strcpy@plt | ppr | printf@got+2 | system[2] | +

strcpy@plt | ppr | printf@got+3 | system[3] | +

printf@plt | exit | &/bin/sh |


위 페이로드를 설명하면, 할당된 스택의 크기와 EBP의 주소에 dummy 값으로 268byte 채워주며, 리턴 주소에 strcpy 함수의 주소를 실어줌으로써 


strcpy 함수가 실행되면서 strcpy 함수가 있던 자리에 함수 프롤로그 과정을 통해 ebp가 push되며, ebp+8, ebp+c 를 참조하여 printf@got에 system 함수


 주소의 1바이트를 덮어 씌우게 되며 함수가 종료되면서 리턴 값에 ppr이 시작하는 주소를 넣어주게 되면, 두 번의 pop 과정을 통해 스택이 8 byte 


증가하면서 esp는 strcpy 함수의 주소를 가르키게 되며 한 번의 ret을 통해 pop eip, jmp eip 명령이 실행되어 또 다시 strcpy 함수가 실행되는 것의 반복이다


[그림 9] - system 함수의 주소를 이루는 각 바이트의 가젯 수집


system = 0x007507c0

c0 = 0x8048420

07 = 0x8048154

75 = 0x80482c8

00 = 0x8048129


[그림 10] - 익스플로잇 코드


[그림 11] - 셸 획득



+ Recent posts