본문으로 바로가기

[pwnable.xyz] xor write up

category CTF/pwnable.xyz 2020. 1. 1. 14:35

 

pwnable.xyz 7번째 문제 xor 이다.

 

실행하면 아래와 같다.

 

 

 

Analyze

이번 문제도 main 함수와 win 함수 말고 특별한 것은 보이지 않는다.

 

gdb 로 main 함수를 분석 해보자.

아래 사진은 main 함수의 일부분이다.

이를 pseudo 코드로 나타내면 아래와 같다.

이번에도 8번째 줄에 Arbitrary overwrite 공격이 가능하다.

 

하지만 main 함수에서 역할은 XOR 연산하는 과정 말고는 없다.

main 함수에 breakpoint를 걸어 vmmap 명령어를 사용하면 아래처럼 0x0000555555554000 ~ 0x0000555555555000 까지 rwxp 권한이 있는 것을 볼 수 있다.

 

 

즉, main 함수에서 특정 주소에 있는 명령어를 변조하여 공격자가 원하는 함수를 실행 할 수 있게 된다.

 

 

main 함수는 반복문이 있는데 main+40에서 돌아와 XOR 연산을 계속 수행한다.

만약 main+60 명령어를 변조하여 win 함수를 호출하는 명령어로 변조하면 win 함수가 실행될 것이다.

 

 

다시 pseudo 코드를 보면 8번째 줄에 rdx + rax = &(main+60) 가 만족하면 된다.

rax = &result 이다. result의 주소는 0x555555756200 이다.

따라서 rdx = 0x202870 이다.

5번째 줄에 의해 rax = -262898 이다.

 

 

rcx 는 변조할 명령어의 16진수 값 이어야 한다.

JMP win 이 명령어를 16진수로 나타내기 위해 아래 주소를 참고 하자.

 

jmp, call instruction 주소 계산

Intel x86 architecture에서 JMP, CALL 명령어는 5Byte로 opcode와 operand는 다음과 같다. ```c JMP : E9 XX XX XX XX CALL : E8 XX XX XX XX ``` 이 때 operand는 절대주소 값이 아니라, 현 위치 기준 상대주소..

umbum.dev

 

위 글을 참고하면 JMP win은 e9 ac ff ff ff 가 된다.

따라서 rcx = 0xfffffface9 가 된다.

4번째 줄에서 rdx과 rcx를 XOR 연산을 하므로 

최종적으로 rcx = 0xfffffface8, rdx=1 이면 된다.

 

 

gdb로 이 값을 넣어 보자.

1099511606504 1 -262898

 

우선 main+40에 breakpoint를 걸고 위에서 구한 값을 넣어보자.

반복문에서 위 값을 XOR 연산 한 후 반복문의 처음으로 돌아오게 된다.

이때 main+60은 명령어가 변조된 것을 확인 할 수 있다. (신기...)

 

Payload

from pwn import *

p = remote("svc.pwnable.xyz", 30029)

p.sendline("1099511606504 1 -262898")
p.interactive()

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

[pwnable.xyz] Grownup write up  (0) 2020.01.25
[pwnable.xyz] two targets write up  (0) 2020.01.02
[pwnable.xyz] xor write up  (0) 2020.01.01
[pwnable.xyz] misalignment write up  (0) 2020.01.01
[pwnable.xyz] add write up  (0) 2019.12.28
[pwnable.xyz] sub write up  (0) 2019.12.28

댓글을 달아 주세요