ROP (64byte) 문제 4번

2019. 4. 27. 23:25System Hacking/ROP(64byte)

prob4


안녕하세요!

오늘은 ROP 64byte

문제 4번을 풀어보도록 하겠습니다!

파일은 제가 위에 놓도록 하겠습니다!


코드를 보니 

지난 3번 문제와 달라진 게 있죠?


3번 문제에선 맨처음에 /bin/sh 문자열을 가진

sh[ ] 배열이 있었는데

이번 문제는 /bin/sh 문자열이 사라졌습니다!


바로 nothing 함수가 있네요!

asm volatile 함수는 

제가 3번 문제에서 알려드렸듯이,

c언어에서 aseembly 코딩을 할 때 쓰는 함수 입니다!


그리고 vuln 함수는

3번 문제와 똑같네요!


버퍼는 16byte만 선언되었는데,

read 함수로 읽어오는 byte가 

무려 256byte나 읽어오네요!


3번과 마찬가지로  버퍼 overflow 문제인데요!


달라진 점은 

(1) /bin/sh가 없다는 것과!

(2) asm volatile( ) 함수의 인자가 바뀌었다는 것!


이것 말고는 나머지 3번과 완전 똑같습니다!



우선 vuln 함수를 peda로 까보았습니다!


나중에 저희가 vuln+42 ret

부분에 breakpoint 걸고

offset 계산해야겠죠?


물론 이론상으론 sub rsp,0x10(=16)이니

16byte + 8byte(ebp) = 24byte dummy

라는 걸 유추 할 수 있지만요!



nothing 함수의 경우 저희가 쓰고 싶은


pop rdi

pop rsi

pop rdx


이 gadget들은 

nothing+4 부터 시작되네요!



그럼 저희가 이론적으로 24byte를 덮어써야 한다!

라고 추측을 해봤는데!


실제로는 얼만큼을 덮어써야 할지!

직접 검증해 보겠습니다!


제가 위에서 말씀드린대로 vuln+42 (ret) 부분에

breakpoint를 겁니다!


그리고

run을 해서 


INPUT: 에다가

pwn cyclic 50 한 아래의 문자 값을 입력해줍니다!


입력을 하면 알아서 

프로그램이 저희가 설정해둔 breakpoint에 걸리게 됩니다!


그리고 값을 확인해보니 0x61616167이 있네요!

그러면 이 값을 복사해서

offset을 계산해봅시다!


cyclic 50은 제가 아까 실행한 명령어구요!


여기서 제가 복사한 0x61616167을 형식에 맞게


" cyclic -l 0x61616167 "


입력하면 아래와 같이 

24가 출력이 됩니다!


한마디로 3번 문제와 마찬가지로 24만큼 덮어씌우면

ret_address가 나온다 이 말이겠죠!



그래서 바로 exploit code 짜보러 가보겠습니다!


payload 부분부터 설명하겠습니다!

e , p , raw_input 부분은 이미 3번 문제에서

설명하였습니다!


payload는 우선 빈칸 ''으로 설정하구요!

저희가 cyclic -l 0x61616167을 통해

얻은 24의 값 (=더미값)

을 써줍니다!


그러면 이제 return address에는 무엇을 써야 할까요?

제가 혹시 위에서 말씀드린거 기억 나시나요?

/bin/sh 문자열이 존재하질 않아요!


저희가 어딘가에 적어야 해요!


그래서 저희는

 

"read 함수로 bss 영역에 /bin/sh 문자열을 적을 거에요!"


근데 read 함수의 인자를 세팅해주기 위해서


pop rdi

pop rsi

pop rdx


위에서 말한 이 gadget을 쓸겁니다


저희가 만들고 싶은 함수의 세팅

read( 0, bss, 8)


p64( ) 함수로

저희가 넣어야 하는 값들 

(1) 0

(2) bss() ->주소

(3) 8 ->읽어들일 문자크기


왜 딱 8입니까? 라고

물으실 분들을 위해

준비했습니다!

 


/bin/sh 문자열 길이가 7입니다!

근데 저희가 enter를 치게 되면

1byte가 추가되어서!


총 8byte로 설정한겁니다!



그리고

read 함수가 끝나면 다시


pop rdi

pop rsi

pop rdx 

을 쓸겁니다!


chaining이 가능하기 때문이죠!


그럼 이제는 무엇을 불러올 것이냐?

system("/bin/sh") 를 불러와야죠!


우선 gadget setting을

nothing +4 로 하구요!


첫 번째 인자에는 bss()에 적은 문자열

/bin/sh! 주소!


두 번째, 세 번째 인자는 없죠!

system( )함수에 /bin/sh만 넣을꺼라서요!


그래서 2,3번째는 모두 0으로 설정을 해줍니다!

그리고 ret에 system함수의 symbol을 읽어 들이면!


system("/bin/sh")가 완성이 됩니다!


밑에는 그냥

함수를 INPUT: 이 출력될때 까지 읽어라


그리고 우리가 작성한 payload를 보내라!

여기서 좀 헷갈릴 수가 있는데!

저희가 먼저 payload를 보내면,


read함수가 호출이 되죠?

저희가 맨처음에 /bin/sh를 적으려고 했으니까요!

그래서 read 함수가


"니가 넣고 싶은 값 적어"

라고 말하면


그때 /bin/sh를 보내는겁니다!

그래서 p.sendline("/bin/sh")를 한겁니다!


p.send("/bin/sh\00")으로도 보낼 수 있는데

p.sendline이 enter까지 같이 넣어서 보내줘서

p.sendline으로 보냈습니다!


이렇게 모든 payload를 잘 보내면

쉘이 획득 될 것이기에!


쉘과 상호작용 하기위해

p.interactive()까지 적으면 

exploit이 완성됩니다!


고생하셨습니다!


'System Hacking > ROP(64byte)' 카테고리의 다른 글

ROP (64byte) 문제 3번  (0) 2019.04.26
ROP (64byte) 문제 2번  (0) 2019.04.24
ROP (64byte) 문제 1번  (0) 2019.04.22