본문 바로가기

Pwnable.kr

Pwnable.kr[loveletter]

실행파일만 있는 상태에서 해당 파일을 분석해보면

 

이름을 입력 받고 해당 이름이 포함된 문자열 "echo I love 'input value' very much!"가

system 함수의 인자로 넘어간다. (asm : main + 465)

 

이 때 system 함수를 통해서 echo를 실행하므로, ; | & 등과 함께 다른 명령어를 삽입하는 방식을 생각했으나

구현되어있는 protect라는 함수에서 

#&;`'"|*?~<>^()[]{}$\,

위의 문자열들을 다른 값으로 치환하는 과정을 거친다.

 

치환되는 값은 mov DWORD PTR [eax], 0xa599e2로 치환을 하는데, (asm : protect + 213)

3바이트 값인데 DWORD PTR을 사용하므로 가장 마지막 바이트는 0x00이 된다. 

 

중간중간 계속 strlen을 이용해서 기존의 문자열 길이를 특수문자 1byte가 3byte 길이로 늘어난 길이를 다시 체크한다.

 

입력값의 경우 fgets를 이용해서 0x100만큼 받고 (asm : main + 139)

 

system 함수를 호출하기 위한 문자열은 하드 코딩 되어 있는 "echo I love ", "very much!" 두 문자열과

사이에 input value를 각각 memcpy를 이용해서 순서대로 (echo~ / input / very ~) 붙이는데,

이 때 idx라는 bss영역의 변수를 통해서 다음 memcpy를 시작할 base + index를 저장한다. 

 

ASLR이 걸려있지 않고, main에서의 ESP는 0xffffdad0

우리의 입력값의 시작주소가 0xffffdae0이니까 ESP+0x10인 상태이다.

 

여기서 idx값의 주소는 ESP+0x110이고, fgets를 통해서 0x100만큼만 입력을 받고 있지만

특수문자를 통한 길이 증가가 가능하기 때문에 idx값을 0으로 만들 수 있다. (치환시 마지막 바이트 0x00됨)

그러기 위해서는 253글자 + 특수문자(#, ', " 등등)로 바꾸면 된다.

 

그렇게 idx값을 0으로 하게 되면

"echo I love "를 memcpy(0x804a0a0 : base)하고,

다시 입력값을 memcpy할 때

0x804a0a0 + idx (0xc)가 시작주소가 되어야 하는데

0x804a0a0 + idx (0x00) == 0x804a0a0이 되어서

echo ~ 부분부터 덮어버린다. 

 

그럼 원하는 명령어를 적을 수 있고, 따로 특수문자 없이 "cat flag dummy"로 253글자를 채우고 

254번째 글자를 필터링에 걸리는 특수문자(#, ', " 등등)로 바꾸면

cat 명령어의 인자로 없는 파일을 읽으려고 시도하는 것 뿐이기 때문에 

앞에 flag는 읽어서 알려주고 뒤에 dummy부터 "very" "much!" 등은 그냥 없는 파일이에요 이러고 끝난다.

 

지적 환영, 배우는 중

'Pwnable.kr' 카테고리의 다른 글

Pwnable.kr [simple login]  (0) 2019.10.16
Pwnable.kr [echo2]  (0) 2019.10.10
Pwnable.kr[fix]  (0) 2019.09.15
Pwnable.kr[tiny_easy]  (0) 2019.09.15
Pwnable.kr[echo1]  (0) 2019.09.14