Notice
Recent Posts
Recent Comments
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Today
Total
관리 메뉴

9oat's LAB

Pwnable.kr input 풀다가 궁금한 거 본문

Study/System

Pwnable.kr input 풀다가 궁금한 거

90at 2017. 7. 16. 17:41

C프로그래밍에 대한 지식은 거의 없다시피 해서 푸는데 꽤 고생하고 오래 걸린 문제였는데, 문제랑 직접적으로 관련 없는 부분에서 이해가 안가는 점이 생겼었다.


먼저 문제에 대해서 설명을 하자면 코딩을 이용해 문제 이름 처럼 여러가지 input(argv,env,socket)으로 값을 넘겨나가는 문제였다.

코딩을 해야하니까 일단 파일을 만들어야 하는데, input 바이너리가 있는 홈 디렉토리(/home/input2)에는 쓰기권한이 없어서, /tmp에 작업공간을 만들어서 풀어야했다. 그리고


[사진 1] input 코드 일부


input 문제코드 중에는 파일을 읽어들이는 코드(\x0a)가 있었는데, 내 생각엔 위와같은 코드일 때 input 바이너리와 동일한 디렉토리에 '\x0a'가 만들어져야 input이 해당 파일을 읽을 수 있다고 생각했다. 하지만 바이너리가 있는 디렉토리엔 파일 생성 권한이 없었기에 input파일과 flag파일 둘 다 심볼릭 링크를 걸어 문제를 풀었었다. 그리고 나서 다른 풀이를 찾아 보는데,  다들 flag파일만 심볼릭 링크를 걸고 문제를 풀었더라.


input을 풀이하는 코딩 구조는 이렇다


1. 요구하는 모든 인자를 구성한다.(이 과정에서 "\x0a"파일을 생성한다.)

2. execv와 같은 실행 함수로 input파일을 실행한다.


위와 같은 코드를 작성해서 실행시키는 것이다.

내 경우에는 2번에서


execv("/tmp/9oat/input",argvs);


와 같이 내가 심볼릭 링크 input파일을 실행시켰고, 다른 풀이의 경우엔


execv("/home/input2/input",argvs);


이런 식으로 실제 input파일을 실행시켰다.


이게 이해가 안가는 것이, input파일이 실행되면 [사진 1]의 코드처럼 '\x0a' 라는 파일을 읽어들여야 한다. 그리고 읽어 들이는 경로는 상대경로로 코딩되어있다. 분명 현재 디렉토리에서 읽어 들이는 걸텐데, input이 실행되는 지점은 /home/input이니까 여기서 '\x0a'를 찾을테고.. 하지만 당연히 거기엔 '\x0a'가 있을 수 없다.  

그런데도 풀이가 되는 걸 보면 input 파일이 '\x0a'라는 파일을 읽었다는 것인데 대체 어떻게 읽은 건지..


상대경로로 코딩했을 때는 현재 디렉토리라는 정보가 있어야한다. 이건 코드 내부에 삽입하는 정보가 아닌데 뭘 보고 판단할 수 있을까?

문득 답은 환경변수가 아닐까 싶었다.


[사진 2] 풀이코드 일부


환경변수로 값을 input해야 하는 스테이지가 있었다. 그래서 풀이코드에 [사진 2]와 같은 코드를 넣었었는데, putenv는 환경변수에 값을 추가하는 함수다. 이렇게 환경변수에 값을 추가한 뒤 execv를 이용해 input을 실행시켰는데, 생각해보니 input이 이 환경변수를 읽을 수 있었다는 것은 풀이코드(이하 pay)와 input이 서로 환경변수공유한다는 것이다. 그리고 환경변수 중에는 현재 디렉토리를 저장하는 PWD 라는 변수가 있다. 환경변수가 공유되므로 PWD 역시 공유된 거라면, 


PAY -> Input


과 같은 실행순서에서, input이 동작할 때 PWD PAY에서 정해진 /tmp/9oat/ 일 것이다. [사진 1] 과 같은 코드에선 현재 디렉토리(PWD)를 기반으로 코드가 동작할테니, /tmp/9oat 에서 동작하므로 "\x0a"를 읽을 수 있게 되는 것 같다.


실제로 PWD를 공유하게 되는 지 실험해봤다.


[사진 3] PWD를 출력하는 프로그램


먼저, 환경변수 PWD출력하는 프로그램을 만들고


[사진 4] [사진 3]을 실행하는 프로그램


다른 경로에서 이 프로그램실행하는 프로그램을 만들었다.

PWD공유된다면, exec라는 프로그램을 실행했을 때, exec의 위치인 /home/goat/Desktop이 출력될 것이다.


[사진 5] 결과


PWD까지 공유되는 것 같다. 아직 한 가지 불확실한 게 있는데, C에서 현재 디렉토리의 정보를 가져올 때, PWD를 사용하는 게 맞는지.. 이게 아니면 지금까지 생각한 것들이 다 의미가 없어진다.


뭐.. 맞겠지?..

Comments