controlpro

[pwnable.xyz] xor 본문

Pwnable/pwnable.xyz

[pwnable.xyz] xor

controlpro 2021. 1. 9. 15:42
728x90

NX에 PIE 그리고 Full Relro 까지 걸려 있는 문제이다. 보호 기법이 많으면 솔직히 하기싫다. ㅠ

 

일단 풀어보자 

일단 문제를 확인해보면 v4 , v5 , v6을 받고 v5와 v4를 xor 연산을 해주고 result[v6] 에 넣어준다. 여기서 문제가 발생한다. if문을 통해서 어느정도 v6 < 9라는 조건을 걸어서 문제가 없어보이지만 v6에 음수가 들어가서 out_of_bound문제가 생기는 경우는 고려하지 않았다. 

 

그러면 result 변수 뒷쪽에 덮을만한 함수가 있어야 한다. 

 

vmmap으로 영역을 보면 rwxp 영역이 존재하는 것을 알 수 있는데 여기에 main 함수 영역이 포함되어 있어서 우리가 코드 부분을 직접 수정이 가능하다. 

근데 result 변수가 저기까지 다을 까? 라는 생각을 할 수도 있는 데 

 

result값이 저기 인것을 봐서는 충분이 다을 거 같다. 

 

1. result[???]에서 ??? 찾기 

 

call exit의 코드는 0xac8이고 result 함수의 값은 0x202200이 되니까

 

(0xac8 - 0x202200) / 8 = -262887 이 offset이 되겠다. 여기서 8 나눠준이유는 idx로 움직이니까 주소공간의 크기만큼 나눠줬다고 바로 생각할 수도 있고, assem 보면 바로 나온다. 

 

offset은 찾아 주었고 무엇을 넣어주면 되는 건가? 그래서 나는 0xa21 넣어주면 생각했다. 

 

2. result[-262887] = ???? 찾기 

결론 부터 말하자면 방금 위에서 했던 생각이 조금 틀렸다. 우리가 평소에는 return address의 주소를 덮었지, 코드의 내용자체를 바꾸지 않아서 덮는 다는 것을 그냥 주소를 덮으면 된다.. 생각했었는데 기계어 코드를 덮어 줘야 한다. 

 

그래서 call을 하는 기계어 코드는 e8 이고 나머지 주소 부분을 덮어주면 된다. call exit할 때  rip 랑 call win 을 할 때 offset이 들어가면된다 . 

 

0xa21 - 0xacd = 0xffff ffff ffff ff54 => 1099511583977

 

 

그러고 입력하면 끝. 

from pwn import *

r = remote('svc.pwnable.xyz' , 30029)

print r.recv(1024)
r.sendline('1 1099511583977 -262887')

print r.recv(1024)
r.sendline('A')
print r.recv(1024)
r.interactive()
~                                                                               
~                    

간단한 문제 였는데 생각보다 푸는 방법이 신기했다. 코드 영역을 직접 덮는 문제는 처음 풀어봐서 좋은 경험이어따!

 

728x90
반응형

'Pwnable > pwnable.xyz' 카테고리의 다른 글

[pwnable.xyz] note  (0) 2021.01.04
[pwnable.xyz] Growup  (0) 2021.01.04