CTF Review Weirdftpd - PowerPoint PPT Presentation

1 / 38
About This Presentation
Title:

CTF Review Weirdftpd

Description:

close(newsockfd); Answer. After receiving a new connection (accept) the program forks ... The two descriptors do not share the close-on-exec flag, however. ... – PowerPoint PPT presentation

Number of Views:65
Avg rating:3.0/5.0
Slides: 39
Provided by: Chris9
Category:
Tags: ctf | close | review | weirdftpd

less

Transcript and Presenter's Notes

Title: CTF Review Weirdftpd


1
CTF Review - Weirdftpd
  • LCDR Eagle

2
Question 1
  • If Weirdftpd performs tcp communications why
    dont we see the use of send and recv anywhere?
  • send is the socket write function
  • recv is the socket receive function
  • All we can find is getchar and printf
  • getchar read a single char from stdin
  • printf - formatted write to stdout

3
Question 2
  • What does this code do?
  • newsockfd accept(csock, client_addr,
    client_len)
  • if (fork() 0)
  • close(0)
  • close(1)
  • dup(newsockfd)
  • dup(newsockfd)
  • close(newsockfd)
  • manage_client()
  • close(0)
  • close(1)
  • exit(0)
  • close(newsockfd)

4
Answer
  • After receiving a new connection (accept) the
    program forks
  • Child process (pid 0) closes stdin and stdout
    and dups the new socket file descriptor onto
    stdin and stdout
  • Child I/O takes place through the socket
  • Parent closes its copy of the socket as it is no
    longer needed

5
W/ Comments
  • //take a new client connection
  • newsockfd accept(csock, client_addr,
    client_len)
  • if (fork() 0) //fork and see if we are the
    child
  • close(0) //close stdin
  • close(1) //close stdout
  • dup(newsockfd) //dup onto next available
    descriptor (0)
  • dup(newsockfd) //dup onto next available
    descriptor (1)
  • close(newsockfd) //close the original
  • manage_client() //go take care of the
    client
  • close(0) //close stdin
  • close(1) //close stdout
  • exit(0) //child process terminates
  • close(newsockfd) //only parent gets here

6
Often See dup2 Instead
  • //take a new client connection
  • newsockfd accept(csock, client_addr,
    client_len)
  • if (fork() 0) //fork and see if we are the
    child
  • dup2(newsockfd, 0) //dup and close in one
  • dup2(newsockfd, 1) //dup and close in one
  • close(newsockfd) //close the original
  • manage_client() //go take care of the
    client
  • close(0) //close stdin
  • close(1) //close stdout
  • exit(0) //child process terminates
  • close(newsockfd) //only parent gets here

7
What is a File Descriptor
  • An integer
  • An index into the file descriptor table
  • Each entry in the table contains a pointer that
    points to an entry in the file table
  • Each file table entry describes an open file
  • Location/size of memory buffers
  • Current read pointer location
  • Current write pointer location
  • Other

8
How Are File Descriptors Created?
  • You get three for free
  • 0
  • refers to the standard input device (stdin)
  • 1
  • Refers to the standard output device (stdout)
  • 2
  • Refers to the standard error device (stderr)
  • open(char name, int flags, int mode)
  • Opens a file and returns a descriptor for it

9
I/O with File Descriptors
  • Reading
  • read(int fd, void buf, uint size)
  • Reads up to size bytes from the specified file
  • Returns
  • -1 error
  • 0 end of file
  • gt 0 number of bytes read
  • Writing
  • write(int fd, void buf, uint size)
  • Writes size bytes to the specified file
  • Returns
  • -1 error
  • gt 0 number of bytes written

10
Redirection
  • Simply change where the file descriptor table
    entry points
  • Example redirecting stdout to a disk file
  • fd 1 still represents stdout, so your program
    remains unchanged
  • The pointer at location 1 in the file descriptor
    table is changed to point to the desired output
    file rather than the console device

11
Redirection
File Descriptor Table
12
fork()
  • Create an exact duplicate of the current process
  • Including current value of all local variables
  • These are copies and can be changed independently
  • Results in two distinct process
  • Both processes continue execution at the point
    that fork returns
  • In the new "child" process, the return value is
    zero
  • In the parent (I.e. the caller), the return value
    is the non-zero process id (pid) of the spawned
    child
  • Used extensively in network server daemons

13
fork() Example
  • int sock socket()
  • bind(sock, )
  • listen(sock, )
  • while (1)
  • int client accept(sock, )
  • if (!fork())
  • //this is the client
  • handleClient(client)
  • break //clients don't loop

14
Sharing Files
  • After a fork, both the parent and the child have
    identical file descriptor tables
  • Each could read/write from/to the same files if
    they wanted
  • It is good practice for each process to close the
    file descriptors that it does not intend to use
  • Only after the last descriptor to a file is
    closed is it truly closed

15
dup/dup2
  • int dup(int oldfd)
  • int dup2(int oldfd, int newfd)
  • dup and dup2 create a copy of the file descriptor
    oldfd.
  • After successful return of dup or dup2, the
    old and new
  • descriptors may be used interchangeably. They
    share locks,
  • file position pointers and flags for
    example, if the
  • file position is modified by using lseek on
    one of the
  • descriptors, the position is also changed for
    the other.
  • The two descriptors do not share the
    close-on-exec flag,
  • however.
  • dup uses the lowest-numbered unused descriptor
    for the new
  • descriptor.
  • dup2 makes newfd be the copy of oldfd,
    closing newfd
  • first if necessary.

16
Exploiting Weirdftpd
  • Preconditions
  • Connect to ftp control port (21)
  • Authenticate (USER/PASS)
  • Overflow (QUIT longstring.)
  • Long string can not contain any \r or \n other
    than at the end
  • Bytes 524-527 of longstring overwrite the return
    address from manage_client
  • The only limit to the amount of data we can send
    in longstring is writing past the highest stack
    address (0xBFFFFFFF on Linux)

17
longstring Layout
ebp points here (last 4 bytes)
Ill call this portion the tail
"QUIT "
524 bytes
4 byte offset
More bytes if we need it
"\r\n"
Shellcode could go either place
18
Choosing an Offset
  • The value with which you overwrite a functions
    return address is usually called the offset
  • It represent the offset of your shell code in the
    stack
  • With stack based overflows this value can not
    always be predicted exactly
  • A debugger can help

19
Using gdb For Offsets
  • To make a good guess at an offset we need to know
    what the stack layout looks like at runtime
  • We can attach gdb to the running ftpd process and
    set a breakpoint
  • Problem
  • The overflow happens in the child process
  • We can not attach gdb to the parent because it
    will stay with the parent after the fork

20
Pausing the Child
  • We need to catch the child before it exits
  • Connect to the ftp port with a telnet client
  • I prefer netcat
  • This gets us past the accept and the fork
  • Child process is created and runs into
    manage_client and get_command
  • Blocks at getchar as long as we send no input
  • Run ps on the victim to get the process id of the
    child

21
Attaching gdb
  • On the victim, cd into the directory containing
    the ftpd binary
  • Issue
  • gdb ftpd ltpidgt
  • Tells gdb you wish to attach to process ltpidgt
    which is a running version of the binary ftpd
  • The child is now under debugger control

22
Setting a Breakpoint
  • We would like to see the stack layout of
    manage_client
  • The program is currently blocking in
    get_command/getchar
  • Set a breakpoint in manage_client at the point
    that get_command returns
  • Disassemble manage_client
  • (gdb) disassemble manage_client

23
Setting a Breakpoint
  • Find the call to get_command
  • 0x080497bf ltmanage_client133gt push eax
  • 0x080497c0 ltmanage_client134gt call 0x8048e58
    ltget_commandgt
  • 0x080497c5 ltmanage_client139gt add 0x10,esp
  • 0x080497c8 ltmanage_client142gt mov
    eax,0xfffff85c(ebp)
  • Set a breakpoint at the statement following the
    call
  • (gdb) b 0x80497c8
  • Allow the program to continue
  • (gdb) cont

24
Triggering the Breakpoint
  • The program continue to block awaiting input
  • In your telnet program issue an ftp login command
  • USER ftp
  • As soon as you press enter, your command will be
    parsed and you will return to manage_client
  • gdb has regained control at the breakpoint

25
Understanding the Stack
  • This program uses ebp based stack frames
  • All we really need to know is the value of ebp
  • (gdb) info reg
  • ebp 8 could be a useful offset
  • That is the address of the first byte in the tail
    section of the payload
  • Problem
  • ebp will vary slightly from child process to
    child process
  • If we are too specific about our offset it may
    not work all the time

26
Taking Control
  • Simple script demo.pl
  • !/usr/bin/perl
  • ltgt
  • print "USER ftp\r\n"
  • print "PASS ftp\r\n"
  • print "QUIT " . 'A'x520
  • print "\xEF\xBE\xAD\xDE\xEF\xBE\xAD\xDE\r\n"
  • Execute it
  • ./demo.pl nc victim 21
  • Attach to child process with gdb and set
    breakpoint
  • Enter a CR in demo.pl window

27
Taking Control
  • Debugger will break after each command from
    demo.pl
  • (gdb) cont //restarts child
  • Continuing.
  • Breakpoint 1, 0x080497c8 in manage_client ()
  • (gdb) cont //after USER
  • Continuing.
  • Breakpoint 1, 0x080497c8 in manage_client ()
  • (gdb) cont //after PASS
  • Continuing.
  • Breakpoint 1, 0x080497c8 in manage_client ()
  • (gdb) x /10xw ebp //examine memory
  • 0xbffff978 0xdeadbeef 0xdeadbeef
    0x0804aa00 0x00000003
  • 0xbffff988 0x4018d3f8 0x00000004
    0x00000001 0x00000000
  • 0xbffff998 0x0000000e 0x00000020

28
NOP Slides
  • If we think the offset may vary /- n bytes then
    we build a NOP slide of size 2n and point offset
    into the middle of it
  • Our shellcode gets appended to the end of the NOP
    slide
  • Control transfers somewhere into the slide and
    NOPs are executed until our shellcode is hit

29
NOP Slide
Low memory
offset
High memory
30
Build An Exploit
  • You have all the basics
  • I refer you to this site for some shellcode
  • http//www.lsd-pl.net/documents/asmcodes.ppt
  • http//www.lsd-pl.net/documents/asmcodes-1.0.2.pdf

31
Weirdftp Operation
  • LCDR Eagle

32
Flag Operations
  • From comments in source
  • case APPE / Read flag /
  • case STAT / Store flag /
  • To access this functionality
  • if (!other !bypass)
  • reply(500,"command not recognizzed")
  • break
  • Variables other and bypass must both be true

33
Getting Through the Gates
  • Variable other is set here
  • if (ftpcommand USER)
  • if (!strncmp(buf, "anonymous",
    strlen("anonymous"))
  • !strncmp(buf, "ftp", strlen("ftp")))
  • command_mode PASSWORD
  • if (buf3 ' ') other 1 //"ftp "
  • Variable bypass
  • Set when compiled in password is matched by PASS
    command
  • In theory this password is unknown to other teams
  • Can't be changed or scoring system can't get in

34
Exploit Strategy
  • When we exploit weirdftpd we get userid ftp
  • This user owns
  • The flag file
  • The ftpd binary
  • Could try for root with a local root exploit
  • Simple service ownage
  • Copy our flag into the flag file /tmp/.x11-unix

35
Flag Copying Problems
  • Other team can copy their flag back at will
  • Restarting ftp server overwrites our planted flag
  • Both of which we overcome by re-exploiting
  • If the other team patches their server we lose
    our way in

36
Better Ownage
  • Patch other teams ftpd to write our key on
    restart
  • Also won't survive recompilation due to patching
  • Start a process as user ftp to periodically
    overwrite the flag
  • Survives patching!
  • Won't survive reboot or kill

37
Best Option
  • Read other team's ftp password out of their
    compiled binary
  • Need to crack with John the Ripper
  • Configure to try lower case alpha only because
    that is all we see in README.flags
  • It helps to have a cracking farm available during
    CTF
  • Once you have this, you can log in just like the
    scorekeepers and place your flag anytime you want
  • Survives patching, reboot and kill!
  • This is the best strategy

38
Improved Weirdftp Security
  • Remember, this is a game!
  • Edit source code to strip all functionality other
    than that required to set and get flags
  • Patch command argument overflow
  • Delete list/retrieve/store/connect_tcpip
    functions
  • Respond only to USER/PASS/APPE/STAT/QUIT commands
Write a Comment
User Comments (0)
About PowerShow.com