[FC3] hell_fire -> evil_wizard : POP POP RET
hint : GOT overwriting
★ memcpy(saved_sfp, buffer+264, 4) : buffer로부터 SFP까지의 거리가 264이다.
Buffer(256) + dummy(4) + SFP(4)
★ strcpy(buffer, argv[1]) : argv[1] 인자로 받은 문자열을 buffer에 복사. 문자열 길이에 상관없이 NULL까지 문자열을 모두 받으므로 bufferoverflow 취약점 존재
★ memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length)) : RET Sleding을 방해하는 것이라고 한다. (int)0xff000000-(int)(buffer+length) 크기만큼을 buffer+length에서부터 0으로 초기화한다. RET Sled 특성 상 계속 RET을 해서 스택 상 고정적인 주소를 exec 계열의 인자로 사용하는데, 그것을 못하게 된 것 같다.
★ setreuid(geteuid(), geteuid()); setregid(getegid(), getegid()); : 프로그램 내에서 setreuid()를 호출하므로 /bin/sh를 실행해도 됨
먼저,POP POP RET에 대해 알아보자.
https://dkalemis.wordpress.com/2010/10/27/the-need-for-a-pop-pop-ret-instruction-sequence/
POP POP RET은 SHE(Structured Exception Handler) exploit을 만들기 위해 필요한 명령어 순서라고 한다. ESP가 high address로 두 번 이동하고 RET이 실행된다.
POP 레지스터가 발생할 때마다, ESP는 high address로 1 word (= 4 byte for 32-bit architecture) 이동한다.
RET이 발생할 때마다, 주소 ESP 포인터의 내용은 EIP에 놓이고 실행된다. 따라서 다른 함수 연속적으로 호출 가능
성공적으로 SEH exploit을 만들기 위해서는 POP POP RET 주소를 찾아야 한다.
(이 문제 같은 경우, 주어졌고 exploit 코드에 사용됐다. 이 문제에서 주어진 exploit.py 코드는 SEH exploit 코드라고 할 수 있겠다.)
이것으로 공격자가 ESP를 higher address로 두 번 이동하게 하고 실행을 ESP가 가리키는 주소로 이동할 수 있다.
#공격 방법::
GOT에 있는 printf 함수의 주소를 system 함수 주소로 덮고,
System 함수 내에 있는 “/bin/sh” 사용
Printf 함수의 PLT, GOT
Strcpy 함수의 PLT
System 함수 주소
“/bin/sh” 문자열 주소 => system 함수의 인자로 넣음
System 함수의 문자 하나하나의 주소를 찾아서 strcpy 함수로 다른 함수의 GOT에 overwrite한다.
#Printf_plt = 0x8048424
#Printf_got = 0x8049884
# "/bin/sh" 주소
system 함수 내 “/bin/sh” 주소 : 0x833603
#Strcpy_plt = 0x8048494
# pop pop ret 주소
Pop pop ret 시작주소 : 0x804854f
#System 함수 문자 주소 구하기
$ objdump -s evil | grep "75" --color=auto
이 방법으로 각각 1바이트씩 문자 주소를 구한다.
#payload
Buffer(256) + dummy(8) + SFP(4) = 268 byte 사용하지 않으므로 A로 채움
GOT의 printf 함수의 주소를 system 함수의 주소로 덮는데는 RTL 사용
RET strcpy 함수의 PLT 주소 넣어서 strcpy 함수가 호출되도록 해서 GOT의 printf 함수 주소 바이트 하나하나를 system 함수 주소 한 바이트씩 덮는다. => for문 사용해 이 과정 각각 4번 반복
이 과정에 POP POP RET이 사용되는데, POP은 ESP 레지스터를 +4 byte 이동시킨다.
POP POP이므로 +8 byte 이동하게 된다.
그리고 RET에 의해 pop eip jmp eip가 실행되어 다른 함수를 연속적으로 호출한다. (Chaining RTL Calls)
strcpy@plt ppr printf@got + 0 0x80484e0 “c0”
strcpy@plt ppr printf@got + 1 0x8048154 “07”
strcpy@plt ppr printf@got + 2 0x80482c8 “75”
strcpy@plt ppr printf@got + 3 0x8048138 “00”
(strcpy@plt ppr printf@got + i system[i] )
GOT에 있는 printf 함수의 주소를 system 함수의 주소로 모두 바꾼 후, printf PLT의 주소를 넣는다. PLT에서는 함수 호출이 처음이 아니면 GOT에서 해당 함수의 주소를 통해 해당 함수를 실행시킨다. 따라서 GOT에 적힌 printf 함수의 주소가 실제 printf 함수의 주소인줄 알고 (사실은 system 함수의 주소) 실행된다. 그리고 RET + 인자 로 system 함수가 구성되므로 RET에는 더 이상 이동하지 않아도 되므로 dummy값을 넣고, 인자는 “/bin/sh”의 주소를 넣어서 “/bin/sh”가 실행되도록 한다.
printf@plt
AAAA
&“/bin/sh”
# exploit 코드
Fork를 해서 성공 시 0을 리턴받으므로 pid가 0이면 execv로 target에 payload를 전달한다.
“get down like that”
[FC3] dark_stone (0) | 2019.07.12 |
---|---|
[FC3] evil_wizard -> dark_stone (0) | 2019.07.12 |
[FC3] dark_eyes -> hell_fire (0) | 2019.07.12 |
[FC3] iron_golem -> dark_eyes (0) | 2019.07.06 |
[FC3] gate -> iron_golem (0) | 2019.07.05 |