CTF Review weirdfind - PowerPoint PPT Presentation

1 / 32
About This Presentation
Title:

CTF Review weirdfind

Description:

FFFEF7A8 envstrings dd 16 dup(?) FFFEF7E8 keyword dd ? FFFEF7EC filename dd ? ... FFFEF7A8 envstrings dd 16919 dup(?) 00000004 r db 4 dup ... – PowerPoint PPT presentation

Number of Views:84
Avg rating:3.0/5.0
Slides: 33
Provided by: Chris9
Category:
Tags: ctf | dd | review | weirdfind

less

Transcript and Presenter's Notes

Title: CTF Review weirdfind


1
CTF Review - weirdfind
  • Evil Thinking 101
  • LCDR Eagle

2
weirdfind Service
  • Compiled binary is /var/sfind/sfind
  • Launched on boot from rc3.d/S91sfind
  • Drops to user sfind
  • Opens UDP listener on port 31337
  • Forks to handle each incoming request
  • Purpose
  • Locate files containing a specified keyword

3
weirdfind Operation
  • Reads a single UDP packet
  • Up to 65536 bytes
  • Passes the packet to manage_request
  • Parses packet contents and performs requested
    operation
  • Request must conform to weirdfind protocol to be
    accepted and processed

4
weirdfind Protocol
  • UDP packet
  • Contents
  • id usersuppliedid\n
  • user username\n
  • password userpassword\n
  • filename searchpattern\n
  • keyword searchterm\n
  • environ optionalenvironmentstrings\n

5
Breaking weirdfind
  • Remember follow the input
  • Where does our packet go?
  • manage_request
  • Audit the manage_request function
  • Problems
  • At least 3 buffer overflows
  • At least 1 information leakage

6
manage_request Flow
  • id does not seem to matter as long as it is
    supplied
  • Our id is returned to us in the reply packet
  • user
  • "whatever" gets us to the sfind functionality
    with proper password
  • "xxxxxxxx " accesses flag set and get
    functionality with proper password
  • x above represents any character. Note the
    trailing space

7
manage_request Flow (cont)
  • user
  • Any other user must exist on the system and
    supply their system password
  • User root with proper root password also gains
    access to flag set and get
  • password
  • For "whatever" password is "ilovethiscompany"
  • For "xxxxxxxx " password is compiled in scoring
    system password
  • For any other user, the user must exist on the
    system and supply the appropriate system password

8
manage_request Flow (cont)
  • filename
  • .c triggers flag write if appropriate
    user/password supplied
  • .h triggers flag read if appropriate
    user/password supplied
  • For whatever/ilovethiscompany the filename is
    used as a parameter to the find command
  • Any other user/pass yields no action

9
manage_request Flow (cont)
  • keyword
  • For flag set this is the new flag to write
  • For flag read this is ignored
  • For sfind functionality this is the keyword
    supplied to the find command
  • environ - optional
  • Space separated environment strings that will be
    set prior to executing the find command
  • These strings will always be set if supplied

10
Restrictions
  • All fields except environ must be supplied and be
    properly formatted
  • Space between command and value
  • \n to terminate line
  • filename and keyword are sanitizeed
  • sanitize function checks for invalid characters
    in filename and keyword string
  • !

11
Restrictions (cont)
  • Sanitize keeps us from doing some really fun
    things which is too bad
  • More importantly it defines characters that our
    shell code cannot contain IF we pass our
    shellcode in the filename or keyword fields

12
Normal Use
  • Ultimately these statements are executed
  • if (getcwd(init_cwd, sizeof(init_cwd)) NULL)
  • perror("getcwd")
  • exit(1)
  • sprintf(outf, "/tmp/weirdfind.d", pid)
  • sprintf(cmd, "find s -name \"s\" -exec grep -H
    -n s
  • " \\\\ \\ s",
  • init_cwd, filename, keyword, outf)
  • system(cmd)

13
What Happens?
  • A find command is built and executed using the
    system function
  • find
  • Searches from init_cwd
  • For files matching our supplied filename
  • For each match it executes grep H n with our
    supplied keyword
  • Results are dumped to file outf whos contents
    are ultimately returned to us in the reply

14
Fun Thing to do 1
  • We supply the keyword to the grep command
  • Why stop at the keyword?
  • Lets throw some switches in there as well
  • The sfind binary lives in init_cwd
  • Lets search it for the embedded scoring password

15
Fun Request 1
  • id myid
  • user whatever
  • password ilovethiscompany
  • filename sfind
  • keyword -a -o XX................
  • Search the file sfind treating it as a text file
    (-a), printing only the matching characters (-o)
    in a pattern starting with XX followed by any 16
    characters

16
Fun Results 1
  • cat request1 nc -u 192.168.1.106 31337
  • id myid
  • /var/sfind/sfind22XX9LFeUKoHaz6
  • This is the hashed password used by the scoring
    system
  • If you can crack it, you can log in with scoring
    system privileges
  • Works because we are allowed to provide
    unanticipated parameters to grep

17
Buffer Overflow 1
  • Remember this
  • sprintf(cmd, "find s -name \"s\" -exec grep -H
    -n s
  • " \\\\ \\ s",
  • init_cwd, filename, keyword, outf)
  • Take a look at the stack of manage_request
  • The command above does unchecked writing to cmd
  • Remember that we control filename and keyword

18
Stack View 1
  • FFFFF7F8 outf db 512 dup(?)
  • FFFFF9F8 cmd db 512 dup(?)
  • FFFFFBF8 init_cwd db 1024 dup(?)
  • FFFFFFF8 var_8 dd ?
  • FFFFFFFC var_4 dd ?
  • 00000000 s db 4 dup(?)
  • 00000004 r db 4 dup(?)
  • outf will only hold about 16 chars
  • /tmp/weirdfind.0
  • init_cwd will only hold about 10 chars
  • /var/sfind
  • If we supply filename and keyword values totaling
    1483 chars or more, we can own the return address
  • Remember, we can supply a packet of up to 64k ?!

19
Triggering Overflow 1
  • id
  • anything we want
  • user/password
  • whatever/ilovethiscompany
  • filename
  • Something short
  • I actually used this to get my return address
    aligned
  • keyword
  • Contains my return address, NOPs and shell code
  • Need to determine a decent return address

20
Buffer Overflow 2
  • By far the easiest to code once you recognize it
  • NO need for NOP slide
  • manage_request calculates the proper return
    address for you AND writes it over the saved
    return address
  • Truly kind of it
  • This one lies in the processing of the optional
    environment strings

21
Declarations
  • char init_cwd1024
  • char cmd512
  • char outf512
  • char replybufBUFSIZE
  • char user
  • char password
  • char filename
  • char keyword
  • char envstrings16
  • Note that they expect no more than 16 environment
    strings

22
The Problem
  • envstrings0 NULL
  • if (!strncmp("environ", p, strlen("environ")))
  • field memchr(p, ' ', strlen(p))
  • if (field NULL)
  • reply(id, "missing environment value",
    sock, addr)
  • return
  • field
  • i 0
  • while (1)
  • envstringsi field //i IS NEVER
    CHECKED!!!
  • p memchr(field, ' ', strlen(field))
  • if (p NULL)
  • p memchr(field, '\n', strlen(field))
  • if (p NULL)
  • reply(id, "malformed environment
    value", sock, addr)
  • return
  • p '\0'

23
Problem Described
  • Scan the supplied environ string
  • Look for the space character
  • Set envstringsi to point to the first character
    following each space
  • Return to 1
  • So, the value placed in envstringsi is the
    address of the ith environment string supplied
    by the client

24
The Stack
  • FFFEF7A8 envstrings dd 16 dup(?)
  • FFFEF7E8 keyword dd ?
  • FFFEF7EC filename dd ?
  • FFFEF7F0 password dd ?
  • FFFEF7F4 user dd ?
  • FFFEF7F8 replybuf dd 16384 dup(?)
  • FFFFF7F8 outf dd 128 dup(?)
  • FFFFF9F8 cmd dd 128 dup(?)
  • FFFFFBF8 init_cwd dd 256 dup(?)
  • FFFFFFF8 var_8 dd ?
  • FFFFFFFC var_4 dd ?
  • 00000000 s db 4 dup(?)
  • 00000004 r db 4 dup(?)
  • I modified this view to look at everything as a
    pointer size (4 byte) variable
  • Given that no checking is performed in the size
    of envstrings

25
Alternative View
  • FFFEF7A8 envstrings dd 16919 dup(?)
  • 00000004 r db 4 dup(?)
  • envstrings is a very large array of char
  • Even better, r is synonymous with
    envstrings16919 (the 16920th supplied
    environment string)
  • Lets supply a lot of environment strings
  • What if we supply our shell code as the 16920th
    envstring?

26
The Magic
  • The envstring parsing algorithm will place the
    address of our shell code into r!
  • We never need to figure out the offset
  • Can we supply 16920 environment strings?
  • We have 65536 bytes we could send
  • If we make each string only 1 char and account
    for the associated space separator
  • 16919 2 chars per string 33838 bytes of
    environment strings
  • Which leaves plenty of room for everything else

27
Buffer Overflow 3
  • This one requires the scoring system password
  • Takes advantage of a buffer overflow in the reply
    function
  • void reply(char id, char buf, int sock,
  • struct sockaddr_in addr)
  • char replybuf65536
  • int result
  • sprintf(replybuf, "id s\ns\n", id, buf)

28
Triggering 3
  • We need
  • strlen(id) strlen(buf) 65536
  • Fortunately we supply id with every request but
    it wont exceed 65536 by itself
  • Here is the stack
  • FFFEFFF8 replybuf db 65536 dup(?)
  • FFFFFFF8 dd ?
  • FFFFFFFC dd ?
  • 00000000 s db 4 dup(?)
  • 00000004 r db 4 dup(?)

29
Creating a Large Buffer
  • There is one way to get a known large buffer
  • We can access it through the flag get/set
    functions
  • The flag is returned as buf when a flag read is
    performed
  • The flag is written from keyword when a flag set
    is performed

30
Triggering 3
  • Assuming we can log in to the flag set/get
    functions
  • Write a very large flag from keyword
  • This should contain your shellcode as well as
    your return address
  • This action alone will not trigger things as the
    large flag is not part of the reply
  • Read back your large flag with a large id
  • The combination of your large id with the
    previously written large id will cause the
    overflow

31
How Large?
  • Knowing the stack structure of reply
  • Compute how many bytes sprintf needs to print to
    cause the overflow
  • Craft a large flag
  • Do the math to determine how large the id field
    should be to cause the overflow on the ensuing
    read flag operation

32
What to do when you get in?
  • All of the buffer overflows yield user sfind
  • The sfind binary is owned by user sfind
  • So it is possible to replace it with a new one
  • One that writes our flag!
  • The flag file is owned by user sfind
  • So it is possible to overwrite it with our flag
Write a Comment
User Comments (0)
About PowerShow.com