2012. 12. 1. 19:40

우선 UPNP는 같은 내부에 자신의 디바이스를 알려주는 용도로 많이 사용 되게 된다. 또한 포트포워딩의 용도로도 사용되게 되는데,

포트포워딩의 경우는 한 아이피당 하나의 포트로 1:1 매칭을 시켜주지만, UPNP 의경우 클라이언트 요청에 따라 유드리 있게 바꿔서 설정이 가능하다는 매리트를 안고 있다. 


프로토콜은 XML 방식을 사용하고 있고 

프로그램관련 내용이나 , XML 개발 내용은 많았으나, 실질적으로 구현된 내용이나, 프로그램은 찾기가 정말 어려운 실정인데, 아래 파일을 구하게 되었다.


진짜 관련 내용 찾느라 2일을 거의다 쓴것 같다.. 


http://www.download32.com/upnp-portmapper-i129031.html

PortMapper-1.9.4.jar


jar 파일이고, 자바가 설치 되어있어야 돌아간다.


이제 wireshark 로 돌아다니는 패킷을 잡아다가 분석해서 어떻게 동작하는지 리포팅 하겠다.

Posted by k1rha
2012. 11. 30. 09:08
프로토콜 설명 내용 

1. 개발 환경

OS : Linux

컴파일러: gcc

UPNP SDK(UPNP 라이브러리) : upnp. sourceforge.net 

IGD (UPNP 데몬): igd.sourceforge.net

 

 

2. 용 어

Device: TV, Gateway 등 장치를 뜻한다. C/S 개념으로 서버와 비슷한 개념이다.

Control Point: Device 를 제어하는 장치로서 일반 PC, 노트북을 예로 들수 있다. C/S 개념으로 클라언트와 비교할 수 있다.

 

 

3. UPNP Layer

UPNP 에는 6 Layer 로 구성되어 있다.

 

 

3

Control

(SOAP)

4

Eventing

(GENA)

5

Presentation

(HTTP:HTML)

 

2  Description (HTTP:XML)

 

1 Discovery (SSDP/GENA)

0 Address

 

 

0 Level (Address

 Control point 와 Device 네트워크에 참여하기 위해 IP Address 를 얻어온다.

1 Level (Discovery)

Control point 는 모든 Device 를 찾아내고 Device 자신의 사용 가능여부를 알려준다.

2 Level (Description)

Control point 가 device 에 대한 기본 정보를 가져 온다.

3 Level (Control)

Control point 가 Device를 제어한다.

4 Level (Eventing)

Control point 가 Device 상태를 listen 한다.

5 Level (Presentation

Web 화면을 Device를 정보를 볼 수 있거나 제어 할 수 있다.

Intel Linux 하에서 구현된 upnp sdk 는 Level 1부터 구현되어 있다. Address를 얻어오는 부분은 DHCP 로 얻어 온다.

4. UPNP 프로토콜과 구현

 

 

Upnp 는 SSDP, GENA, SOAP 로 구성되어 있다. SSDP와 GENA 는 UDP 기반위에 멀티 캐스트/유니캐스트 패킷으로 이뤄어 졌고 SOAP는 TCP 기반으로 구성되어 있다. 약간씩 차이는 있지만 기본적인 형태는 HTTP로 이루어 졌기 때문에 UPNP SDK 를 살펴보면 WEB 모듈이 반이상을 차지하는 것을 알 수 있다.


 

 


1) Discovery(SSDP/GENA)

 

Device를 네트워크에 참여시키면 239.255.255.250 패킷 헤더에 NOTIFY , 장치의 고유번호 , 동작여부, Device 를 정의한 xml 파일의 경로 등을 담은 멀티캐스트 udp 패킷을 네트워크로 보낸다(광고한다).

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
CACHE-CONTROL: max-age =
 1800
LOCATION: http://192.168.0.9:2869/gatedesc.xml

NTupnp:rootdevice
NTS
ssdp:alive
SERVER: Linux/2.4.12 UPnP/1.0 Intel UPnP SDK/1.0
USNadvertisement UUID

 

 

 


* 이 부분은 upnp sdk 에서 구현되어 있으므로 사용자가 프로그램 해야 할 부분은 UpnpSendAdvertisement 함수를 호출 해주면 된다.

 

 

 

2) Description (HTTP:XML)

Discovery에서 알아낸 Device의 XML description 파일을 얻어 온다. 프로토콜 방식은 HTTP 방식이다.

 

PC 에서 Description 패킷을 받으면 [내 네트워크 환경]에서 Device 가 나타나는걸 볼 수 있다. 이 아이콘을 누르면 바로 Device의 설정화면인 Web 화면으로 넘어간다. Anygate 상에서는 Description 부분이 구현되어 있다면 Device 의 IP 주소를 몰라도 이 아이콘의 클릭만으로 바로 설정 화면으로 들어갈 수 있다.

 

위에 등록 정보 내용을 수정하려면 xml 파일을 수정하면 된다. 우리는 gatedesc.xml 의 기본내용을 담고 있는 gatedesc.skl에서 각 내용을 수정할 수 있다

 

 

3) Control (SOAP)

Control pointer 에서 Device의 정보를 얻어오거나 Device를 제어할 때 사용되는 Control Level 은 Device와 관련된 부분으로 Anygate에 상에 upnp 를 돌리기 위해 가장 많이 구현해야 하는 부분이다.

해더부분은 M-POST 로 시작하며 SOAPACTION 뒤에 오는 각각의 #ActionName(제어시) 과 #QueryStateVariable(Device에 대한 정보) 요청에 대한 응답 부분을 구현해야 한다.

 

M-POST  /upnp/control/WANIPConn1  HTTP/1.1
HOST: 192.168.0.9:2869  CONTENT-TYPE: text/xml; charset="utf-8"
MAN: "http://schemas.xmlsoap.org/soap/envelope/"; ns=0101-

==============================================================

Device를 제어 할 때

SOAPACTION: "urn:schemas-upnp-org:service:serviceType:v#actionName"
==============================================================

Device의 정보를 알고자 할 때

SOAPACTION: "urn:schemas-upnp-org:control-1-0#QueryStateVariable

 

 


 

 

Device 에는 여러 개의 Service 로 이루워져 있는데 인터넷 공유기인 Anygate 는 IGD 를 기반으로 하기 때문에 연결부분 (CONNECT), 설정 부분(CONFIG), Device 의 OS 3개 부분으로 구성되어 있고 각각을 정의한 description 파일 gateconnSCPD.xml, gateicfgSCPD.xml,  gateinfoSCPD.xml 3개가 존재 한다.

 

각각의 서비스에 대한 Action 값은 igd.sourceforge.net 에 정의 되어 있으나 각 부분에 대한 값들은 구현을 해야 된다.

 

if (strcmp(ca_event->ServiceID, GateServiceId[GATE_SERVICE_CONNECT]) == 0)

=>서비스 종류 확인

{

strcpy(service_type, GateServiceType[GATE_SERVICE_CONNECT]);

if (strcmp(ca_event->ActionName, "GetConnectionTypeInfo") == 0)

=> Action 종류 확인

{

action_succeeded = 1;

strcpy(result_param,"<NewConnectionType>IP_Routed</NewConnectionType>

<NewPossibleConnectionTypes>IP_Routed</NewPossibleConnectionTypes>");

=> 이부분이 Device 장치와 관련 부분으로 사용자가 정의 해야 한다.

}

}

ca_event->ErrCode = UPNP_E_SUCCESS;

sprintf(result_str, "<u:%sResponse xmlns:u=\"%s\">\n%s\n</u:%sResponse>",

ca_event->ActionName,service_type,result_param,ca_event->ActionName);

=> Action 이름/ 서비스 종류/ Action 에 대한 value 값을 result_str 에 복사한 다음  result_str 값을 Control point에 보내주면 된다.

 


 

 

 

 


각 서비스에 대한 Action 과 구현은 아래와 같다.

 

연결 부분 (GateServiceId[GATE_SERVICE_CONNECT])에 대한 Action

 

- GetConnectionTypeInfo: 연결 타입으로 IP_Routed 로 정의

- GetNATRSIPStatus: NAT 사용 여부 로 Enable 값은 1로 정의

- GetStatusInfo: 연결 여부, 연결 시간

  Uptime => /proc/uptime 을 이용한다.

- GetExternalIPAddress: 외부 IP 주소

- GetGenericPortMappingEntry: 기본적으로 내장되어 있는 포트포워딩 으로 아래와 같은 값은 만들어서 보내줘야 동작 한다. 
포트 포워딩에 관련된 값들은 호스트 아이피, 외부 포트, 프로토콜, 내부 포트, 내부 아이피 , 사용여부,  포트 포워딩 설명, 사용 시간에 대한 내용을 표시하여 한다. 각각의 값은 아래 굵은 글씨를 참조하면 된다.

<NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost>

<NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">23</NewExternalPort>

<NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">TCP</NewProtocol>

<NewInternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">23</NewInternalPort>

<NewInternalClient xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"> 192.168.1.0 </NewInternalClient>

<NewEnabled xmlns:dt="urn:schemas-microsoft-com:datatypes"dt:dt="boolean">0</NewEnabled>

<NewPortMappingDescription xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"> Telnet </NewPortMappingDescription>

<NewLeaseDuration xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui4"> 0 </NewLeaseDuration>

 



- GetSpecificPortMappingEntry: 사용자가 직접 입력한 포트 포워딩 Entry

- AddPortMapping : 포트 포워딩 규칙이 추가될 때 동작 한다.

- DeletePortMapping : 포트 포워딩 규칙이 추가될 때 동작 한다.

 

GateServiceId[GATE_SERVICE_CONFIG]

이부분은 RX_PACKET /TX_PACKET 흐름에 대한 정보를 표현한 것으로 -> /proc/net/dev 에서 가져오면 된다.

 

- GetTotalPacketsSent 인터넷 게이트웨이가 보낸 패킷

- GetTotalPacketsReceived 인터넷 게이트웨이가 받은 패킷

- GetCommonLinkProperties: 연결 상태, 속도

 

GateServiceId[GATE_SERVICE_OSINFO]

 

 

UPNP 에서 Control 패킷을 받으면 [내트워크 연결] 를 보면 인터넷 게이트웨이에 Gateway를 설정할 수 있는 부분이 생겼다는걸 알수 있다.

 

위 아이콘을 클릭하면 연결 상태, 기간, 속도, 인터넷 게이트 웨이에서 주고 받은 패킷에 대한 정보가 나온다. 이부분은 Action 을 계속하여 보내므로써 출력된다. 

 

4) Eventing (GENA)

Control Point Device의 정보를 광고 정보를 subscribe , unsubscribe 할때 받는 패킷으로 헤데 부분에 SUBSCRIBE, UNSUBSCRIBE 로 구현되어 있다.

SUBSCRIBE /upnp/event/OSInfo1 HTTP/1.1
HOST: 192.168.0.9
CALLBACK
: <http://192.168.0.79:5000/notify>..
NTupnp:event
TIMEOUT: Second-requested subscription duration

 



5) Presentation

이부분은 일반 HTTP 프로토콜과 같다.

5. Upnp 실행

 

1) 멀티 캐스트 패킷을 받아야 하므로 멀티캐스킹에 라우팅 규칙을 추가해야 한다.

route add -net 239.0.0.0 netmask 255.0.0.0 eth0

upnp 실행 시키려면 [upnpd 외부 IF 내부 IF ] 명령어를 실행하면 된다.

ex)upnpd eth1 eth0

Posted by k1rha
2012. 11. 29. 02:28


웹쉘 에사용되는 함수 점검하는 스크립트~ (Script, Finding using function in webshell) 


간단하게 짜보았는데, 단점은 result.txt 까지 검사를 한다.. 

result.txt 는 상위 폴더에 넣고 그폴더만 검색하도록 하는것을 권장! 


#!/bin/bash

echo "START"

grep -r -n "system(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' > result.txt

grep -r -n "execl(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "execve(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "fopen(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "passthru(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "exec(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

grep -r -n "shell_exec(" ./ | awk -F : '{print "filename : "$1"\nline: "$2"\nmatch: "$3"\n\n"}' >> result.txt

echo "create file \"result.txt\""

echo "FINISH"

Posted by k1rha
2012. 11. 28. 05:25

[출처 :http://tran.kr/94 ] 

맨날 직접 짜다보면 빠트리는 구문이 생겨버리는 구절.. 아예 가지고 있어야 겠다.



  1: #include <stdio.h>
  2: #include <string.h>
  3: #include <stdlib.h>
  4: #include <unistd.h>
  5: 
  6: int main(int argc, char **argv)
  7: {
  8:    char  optstring[1024];
  9:    extern char *optarg;
 10:    int   optchar;
 11:    
 12:    
 13:    memset(optstring, 0x00, sizeof(optstring));
 14:    
 15:    sprintf(optstring, "%s", "d:h:");
 16:    
 17:    while((optchar = getopt(argc, argv, optstring)) != EOF)
 18:    {
 19:       
 20:       switch(optchar)
 21:       {
 22:          case 'd':
 23:             printf("option d = [%s] \n", optarg);
 24:             break;
 25:          
 26:          case 'h':
 27:             printf("option h = [%s] \n", optarg);
 28:             break;
 29:             
 30:          default :
 31:             break;
 32:       }
 33:    }
 34:    
 35:    printf("End\n");
 36:    
 37:    return 0;
 38: }

Posted by k1rha
2012. 11. 28. 05:24

리눅스 계정 만료는 

/etc/shadow 에서 관리해준다.

여기에 암호화된 암호정보와, : : : 구분자로 만료일을 결정해 주게 되는데, 이 만료일이 다 되게 되면

암호를 바꿔달라고 요청이 뜨면서 재부팅 현상이 일어나게 된다. 

QEMU에서 passwd 명령어를 통해 암호를 바꿀 시 이 만료일이 다 되었다고

your password has expired 라는 문구가 뜨는 바람에 검색을 좀 오래 했다. 


아래는 개인 리눅스 서버의 shadow 파일정보이다. 

iptime2:$6$.uvg2DgO$ZLHPlEusVDJTWup/fl0YtsHUZGi8oYauPs97wc8P.opRnJVZPhuh5r8ba3vOrwrTwe895PoDqszJbbsL.T/v70:15641:0:99999:7

vde2-net:*:15646:0:99999:7:::

bind:*:15655:0:99999:7:::

QEMU:!:15656:0:99999:7:::

Posted by k1rha
2012. 11. 26. 06:59

http://code.google.com/p/xe-core/source/browse/branches/1.5.3.2/modules/install/install.admin.controller.php?spec=svn12278&r=12278

Posted by k1rha
2012. 11. 25. 15:47

http://blog.naver.com/giveupyou?Redirect=Log&logNo=20145878587


비교 분석이 잘되어 있는 블로그이다.


Posted by k1rha
2012. 11. 14. 20:36

[출처 : http://kuniz37.tistory.com/38 ]


1. lighttpd의 설치
  > sudo apt-get install lighttpd

2. 포트 변경
  > sudo vi /etc/lighttpd/lighttpd.conf

# 아래 문장 추가
server.port = 8081   


3. 디렉토리 view disable하기
 > sudo vi /etc/lighttpd/lighttpd.conf

server.dir-listing = "disable"


 
4. lighttpd cgi 사용 
 > sudo vi /etc/lighttpd/lighttpd.conf

server.modules = (
       ...
      "mod_cgi",                          # 추가


cgi.assign = (".cgi" => "")            # 추가   //이게 없으면 실행이안됨

 # ".cgi" => ""  (자체 실행을 의미) ,  
 # ".pl" => "/usr/bin/perl"  (.pl일 경우 perl 프로그램을 실행)

5. 개인화 폴더 설정 ( http://redmine.lighttpd.net/wiki/1/Docs:ModUserDir )
 > sudo vi /etc/lighttpd/lighttpd.conf

server.modules = (

...
"mod_userdir", 

)

userdir.path = "public_html"    # ~ 아래의 폴더를 웹 페이지의 메인으로 선택
userdir.exclude-user = ("root", "postmaster")  # 사용하지 않을 유저 설정 


6. ssl 설정 ( http://redmine.lighttpd.net/wiki/1/Docs:SSL )
 > sudo vi /etc/lighttpd/lighttpd.conf

$SERVER["socket"] == ":8082" {

ssl.engine = "enable"
ssl.pemfile = "/var/www/ssl/myserv.pem" 

 인증서 파일은 보안 설정을 400으로 할 것!

7. 서버 재시작
 > sudo /etc/init.d/lighttpd restart

Posted by k1rha
2012. 11. 14. 20:18

tcpdump -s 1000 (1000 개만 출력)

tcpdump -s -X (char 형으로 출력하는 것을 포함함)

tcpdump -s 1000 src 222.222.222.222 -X (출발지 아이피가 222.222.222.222  인것만 출력)

tcpdump -s 1000 src 222.222.222.222 and dst port 80 -X  (port 가 80 번 인것만 출력)



Posted by k1rha
2012. 11. 14. 20:01

CGI 는 웹서버에서 최경량으로 사용할 수 있또록 만든 서버 언어라고 보면 된다. 


CGI 파일은 일반적인 C언어에 CGI만의 환경변수들을 추가 함으로써 처리가 이뤄지게 된다.


첫째로 CGI 프로그래밍에서 첫번째 규약은 시작이 \n 로 되어야 한다. 그래서 대부분 CGI 파일의 시작은


printf("contents-type \n\n") // 처음 엔터부분

으로 시작하는 경우가 많다.


변수의 전달은 query_string 으로 가져오고  Request_URL 는 주소값 전체가 들어가 있다.


즉 /cgi-bin/test.cgi?aaaa=bbbbb

라고 했을때 

getenv("QUERY_STRING"); 의 결과 값으로 aaaa=bbbbb  가 들어가 있게 되고 

getenv("REQUEST_URL); 의 결과 값으로 /cgi-bin/test.cgi?aaaa=bbbbbb 가 들어가 있게 된다.


여러개의 변수를 저장할때는 & 로 가져오기 때문에

가져올때는 &로 짤라서 써야 한다.

보통 strtok 이나 strstr 의 포인터 값을 이용하여 문자열을 파싱해서 끄게 된다.


p=getenv("QUERT_STRING");

reuslt > aaaa=bbbb&cccc=ddddd



REQUEST_METHOD 는 변조가 불가능한 타입이고 , GET, POST 두개의 값으로 전달 되는 경우가 많다.

Posted by k1rha