def dblreq(): ''' Extra Trailing Octets in a UDP Datagram This message contains a single SIP REGISTER request, which ostensibly arrived over UDP in a single datagram. The packet contains extra octets after the body (which in this case has zero length). The extra octets happen to look like a SIP INVITE request, but (per section 18.3 of [RFC3261]) they are just spurious noise that must be ignored. A SIP element receiving this datagram would handle the REGISTER request normally and ignore the extra bits that look like an INVITE request. If the element is a proxy choosing to forward the REGISTER, the INVITE octets would not appear in the forwarded request. ''' log = logging.getLogger('dblreq') log.info('Testing module: %s' % module_info['test']) msg1 = buildreq.makeRequest('REGISTER') msg2 = buildreq.makeRequest('INVITE') mline, head, body = parseSIPMessage(msg1) # Tweak 1: Add the body of msg1 as msg2, short hack body = '\r\n%s' % msg2 # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def bcast(): ''' 200 OK Response with Broadcast Via Header Field Value The message is well formed; parsers must not fail when receiving it. An endpoint receiving this message should simply discard it. If a proxy followed normal response processing rules blindly, it would forward this response to the broadcast address. To protect against this as an avenue of attack, proxies should drop such responses. ''' bcastaddr = '255.255.255.255' log = logging.getLogger('bcast') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) # Tweak 1: The message header first mline = 'SIP/2.0 200 OK' # Tweak 2: Add another via header head['via'] = 'SIP/2.0/UDP %s;branch=z9hG4bK-%s' % (bcastaddr, random.getrandbits(32)) # Recompiling our message mg = catMetHead(mline, head, body=body) return mg
def escnull(): ''' Escaped Nulls in URIs This register request contains several URIs with nulls in the userpart. The message is well formed - parsers must accept this message. Implementations must take special care when unescaping the Address-of-Record (AOR) in this request so as to not prematurely shorten the username. This request registers two distinct contact URIs. ''' log = logging.getLogger('escnull') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseMsg(msg) # Tweak 1: modify to and from headers head['To'] = re.sub(r'sip:\w+?@', 'sip:null-%s-null@' % NULL_CHAR, head.get('To')) head['From'] = re.sub(r'sip:\w+?@', 'sip:null-%s-null@' % NULL_CHAR, head.get('From')) # Tweak 2: Modify the contact header head['Contact'] = re.sub(r'sip:\w+?@', 'sip:%s@' % NULL_CHAR, head.get('Contact')) head['CONTACT'] = re.sub(r'sip:\w+?@', 'sip:%s@' % (NULL_CHAR * 5), head.get('Contact')) # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def unkauth(): ''' Unknown/Invalid Authorization Scheme The request is well formed. A parser must not fail when receiving it. A proxy will treat this request as it would any other REGISTER. If it forwards the request, it will include this Authorization header field unmodified in the forwarded messages. A registrar that does not care about challenge-response authentication will simply ignore the Authorization header field, processing this registration as if the field were not present. A registrar that does care about challenge-response authentication will reject this request with a 401, issuing a new challenge with a scheme it understands. Endpoints choosing not to act as registrars will simply reject the request. A 405 Method Not Allowed is appropriate. ''' log = logging.getLogger('unkauth') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseMsg(msg) # Tweak 1: Add invalid auth scheme head['Authorization'] = '%s %s' % (genRandStr(15), 'randparam-data=valuehere') mg = catMetHead(mline, head, body=body) return mg
def unkscm2(): ''' Unknown Request URI with Unknown Scheme in Header Fields This message contains registered schemes in the To, From, and Contact header fields of a request. The message is syntactically valid. Parsers must not fail when receiving this message. Proxies should treat this message as they would any other request for this URI. A registrar would reject this request with a 400 Bad Request response, since the To: header field is required to contain a SIP or SIPS URI as an AOR. ''' log = logging.getLogger('unkscm2') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseMsg(msg) # Tweak 1: modify the header URI scheme head['To'] = '%s:%s' % (genRandStr(4), random.getrandbits(32)) fromhead = head['From'] head['From'] = fromhead.replace(fromhead.split(';')[0], '<http://example.com>') head['Contact'] = '<name:siptorch_flames>' # Forming the request message back up mg = catMetHead(mline, head, body=body) return mg
def invdisp(): ''' Non-token Chars in Display Name This OPTIONS request is malformed, since the display names in the To and From header fields contain non-token characters but are unquoted. It is reasonable always to reject this kind of error with a 400 Bad Request response. An element may attempt to be liberal in what it receives and infer the missing quotes. If this element were a proxy, it must not propagate the error into the request it forwards. As a consequence, if the fields are covered by a signature, there's not much point in trying to be liberal - the message should simply be rejected. ''' log = logging.getLogger('invdisp') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify add untokenized header display names head['From'] = '%s, %s <sip:%s@%s>;tag=%s' % ('siptorch', 'testing', config.DEF_EXT, config.RHOST, random.getrandbits(32)) head['To'] = '%s, %s, %s <sip:%s@%s>' % ('server', "shouldn't", 'break', config.DEF_EXT, config.RHOST) mg = concatMethodxHeaders(mline, head, body=body) return mg
def inv2543(): ''' INVITE With RFC 2543 Syntax Support This is a legal message per RFC 2543 (and several bis versions) that should be accepted by RFC 3261 elements that want to maintain backwards compatibility. ''' log = logging.getLogger('inv2543') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseSIPMessage(msg) # Tweak 1: Remove branch parameter from Via head['Via'] = rmallParam(head['Via']) # Tweak 2: Remove from tag head['From'] = rmspcParam(head['From'], param='tag').replace('>', '') + ';user=phone>' # Tweak 3: Remove the following headers rmhead = ( 'Allow', 'Contact', 'Max-Forwards', 'Content-Length' ) for x in rmhead: head.pop(x, None) # Forming the request message back up mg = concatMethodxHeaders(mline, head, body=body) return mg
def baddate(): ''' Invalid Time Zone in Date Header Field This INVITE is invalid, as it contains a non-GMT time zone in the SIP Date header field. It is acceptable to reject this request as malformed (though an element shouldn't do that unless the contents of the Date header field were actually important to its processing). An element wishing to be liberal in what it accepts could ignore this value altogether if it wasn't going to use the Date header field anyway. Otherwise, it could attempt to interpret this date and adjust it to GMT. RFC 3261 explicitly defines the only acceptable time zone designation as "GMT". "UT", while synonymous with GMT per RFC 2822, is not valid. "UTC" and "UCT" are also invalid. ''' log = logging.getLogger('baddate') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) x = datetime.datetime.now() # Tweak 1: Add non-GMT timezone to date header head['Date'] = '%s, %s %s %s %s EST' % (x.strftime('%a'), x.strftime('%d'), x.strftime('%b'), x.strftime('%Y'), x.strftime('%X')) mg = catMetHead(mline, head, body=body) return mg
def unkscm(): ''' OPTIONS Request URI with Unknown Scheme This OPTIONS contains an unknown URI scheme in the Request-URI. A parser must accept this as a well-formed SIP request. An element receiving this request will reject it with a 416 Unsupported URI Scheme response. Some early implementations attempt to look at the contents of the To header field to determine how to route this kind of request. That is an error. Despite the fact that the To header field and the Request URI frequently look alike in simplistic first-hop messages, the To header field contains no routing information. ''' log = logging.getLogger('unkscm') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseMsg(msg) # Tweak 1: modify the request URI scheme mline = mline.replace(mline.split(' ')[1], 'unknownscheme:unknowncontent') # Forming the request message back up mg = catMetHead(mline, head, body=body) return mg
def escinv(): ''' Use of % When It Is Not an Escape In most of the places % can appear in a SIP message, it is not an escape character. This can surprise the unwary implementor. A parser should accept this message as well formed. A proxy would forward or reject the message depending on what the Request-URI meant to it. An endpoint would reject this message with a 501. ''' log = logging.getLogger('escinv') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseSIPMessage(msg) # Tweak 1: modify the register header newmeth = urlEncodeStrInvalid('EGISTER', randomchoice=True, value=2) # Making sure the first byte is not URL encoded newmeth = '%s%s' % ('R', newmeth) mline = mline.replace(mline.split(' ')[0], newmeth) # Tweak 2: Modify the to and from headers head['To'] = re.sub(r'\"\w+?\"', '"%Z%45"', head.get('To')) head['From'] = re.sub(r'\"\w+?\"', '"%Z%45"', head.get('From')) # Tweak 3: Change the Cseq header head['CSeq'] = '%s %s' % (head.get('CSeq').split(' ')[0], newmeth) # Tweak 4: Change a contact header newct = '%s%s' % ('C', urlEncodeStrInvalid('ontact', value=1)) head[newct] = re.sub(r'sip:\w+?@', 'sip:6969@', head.get('Contact')) # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def multireq(): ''' Multiple Values in Single Value Required Fields An element receiving this request would respond with a 400 Bad Request error. ''' log = logging.getLogger('multireq') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) # Tweak 1: Add multiple keys with same value duplicate # The RFC 3261 says that the SIP message is not case-sensitive # So what we do to exploit this is, lowercase the keys to form # duplicates, since in no way a dict can hold duplicates # # Duplicating the following fields - call-id, to, from, max- # forwards, cseq headers head['call-id'] = random.getrandbits(80) head['cseq'] = '600 INVITE' head['to'] = 'sip:6969@%s' % config.RHOST head['from'] = 'sip:2020@%s;tag=%s' % (config.RHOST, random.getrandbits(32)) head['max-forwards'] = '5' # Recompiling our message mg = catMetHead(mline, head, body=body) return mg
def unreason(): ''' Unusual Reason Phrase This 200 response contains a reason phrase other than "OK". The reason phrase is intended for human consumption and may contain any string produced by Reason-Phrase = *(reserved / unreserved / escaped / UTF8-NONASCII / UTF8-CONT / SP / HTAB) This particular response contains unreserved and non-ascii UTF-8 characters. This response is well formed. A parser must accept this message. ''' log = logging.getLogger('unreason') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify the header of the message # We are using a 20 char to form the remaining utfencstr = r'e0a6a4e0a6ace0a78720e0a68fe0a695e0a6b6e0a' utfencstr += r'78b20e0a6a8e0a6bfe0a6b0e0a6bee0a6a8e0a6ace0a78de' utfencstr += r'0a6ace0a68720e0a6afe0a6a5e0a787e0a6b7e0a78de0a' utfencstr += r'69f20e0a6b8e0a6b9e0a69c20e0a69be0a6bfe0a6b2' mline = 'SIP/2.0 200 = %s * %s %s' % ( '2**5', '5**2', bytearray.fromhex(utfencstr).decode('utf-8')) # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def semiuri(): ''' Semicolon-Separated Parameters in URI User Part This request has a semicolon-separated parameter contained in the "user" part of the Request-URI (whose value contains an escaped @ symbol). Receiving elements will accept this as a well-formed message. The Request-URI will parse so that the user part is "user;[email protected]". ''' log = logging.getLogger('semiuri') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify the header options uri newuri = mline.split(' ')[1] nuri = '%s;param=u%sinfectedsip.net@%s' % ( newuri.split('@')[0], r'%40', newuri.split('@')[1]) mline = mline.replace(mline.split(' ')[1], nuri) # Tweak 2: Add the Accept header head['Accept'] = 'application/sdp, application/pkcs7-mime, ' head['Accept'] += 'multipart/mixed, multipart/signed, ' head['Accept'] += 'message/sip, message/sipfrag' # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def reqsclarg(): ''' Request Scalar Fields with Overlarge Values An element receiving this request should respond with a 400 Bad Request due to the CSeq error. If only the Max-Forwards field were in error, the element could choose to process the request as if the field were absent. If only the expiry values were in error, the element could treat them as if they contained the default values for expiration (3600 in this case). Other scalar request fields that may contain aberrant values include, but are not limited to, the Contact q value, the Timestamp value, and the Via ttl parameter. (Not implemented, maybe later). ''' log = logging.getLogger('reqsclarg') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify the max-forwards header head['Max-Forwards'] = '300' # Tweak 2: Add large scalar value in cseq head['CSeq'] = head.get('CSeq').replace( head.get('CSeq').split(' ')[0], str(random.getrandbits(100))) # Tweak 3: Add Expires value > 2**32-1 head['Expires'] = '1' * 100 # Tweak 4: Contact header expires header head['Contact'] += ';expires=%s' % random.getrandbits(100) # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def respsclarg(): ''' Response Scalar Fields with Overlarge Values This response contains several scalar header field values outside their legal range (>2**32-1). Note that the Warning header too has value greater than 3 digits. An element receiving this response will simply discard it. ''' log = logging.getLogger('respsclarg') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify the method line mline = 'SIP/2.0 503 Service Unavailable' # Tweak 2: Add retry after header head['Retry-After'] = '%s' % random.getrandbits(100) # Tweak 3: Add warning header head['Warning'] = '%s overture "In Progress"' % \ random.randint(1000, 9999) # Tweak 4: Add large scalar value in cseq head['CSeq'] = head.get('CSeq').replace( head.get('CSeq').split(' ')[0], str(random.getrandbits(100))) # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def mpmime(): ''' Multipart MIME Message This MESSAGE request contains two body parts. The second part is binary encoded and contains null (0x00) characters. Receivers must take care to frame the received message properly. Parsers must accept this message as well formed, even if the application above the parser does not support multipart/signed. Additional examples of multipart/mime messages, in particular S/MIME messages, are available in the security call flow examples document. ''' log = logging.getLogger('mpmime') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('MESSAGE') mline, head, body = parseMsg(msg) # Message to be sent over cer = r'3082015206092A864886F70D010702A08201433082013F02' cer += r'01013109300706052B0E03021A300B06092A864886F70D010701318201203082' cer += r'011C020101307C3070310B300906035504061302555331133011060355040813' cer += r'0A43616C69666F726E69613111300F0603550407130853616E204A6F7365310E' cer += r'300C060355040A1305736970697431293027060355040B132053697069742054' cer += r'65737420436572746966696361746520417574686F7269747902080195007102' cer += r'330113300706052B0E03021A300D06092A864886F70D01010105000481808EF4' cer += r'66F948F0522DD2E5978E9D95AAE9F2FE15A06659716292E8DA2AA8D8350A68CE' cer += r'FFAE3CBD2BFF1675DDD5648E593DD64728F26220F7E941749E330D9A15EDABDB' cer += r'93D10C42102E7B7289D29CC0C9AE2EFBC7C0CFF9172F3B027E4FC027E1546DE4' cer += r'B6AA3ABB3E66CCCB5DD6C64B8383149CB8E6FF182D944FE57B65BC99D005' # Boundary to be used boundary = genRandStr(16, allow_digits=True) # Tweak 1: Add a route header head['Route'] = '<sip:127.0.0.1:5080>' # Tweak 2; Add the identity header head['Identity'] = config.IDENTITY # Tweak 3: Add cte header to binary head['Content-Transfer-Encoding'] = 'binary' # Tweak 4: Add multipart/mixed to content type head['Content-Type'] = 'multipart/mixed;boundary=%s' % boundary # Tweak 5: Add the body body = '--%s\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding' % boundary body += ': binary\r\n\r\nHi from siptorch - pls dont break\r\n--%s\r\n' % boundary body += 'Content-Type: application/octet-stream\r\nContent-Tran' body += 'sfer-Encoding: binary\r\n\r\n%s\r\n--%s--' % ( bytearray.fromhex(cer).decode('utf-8', errors='ignore'), boundary) # Tweak 6: Add content-length header head['Content-Length'] = len(body) # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def longreq(): ''' Long Values in Header Fields This well-formed request contains header fields with many values and values that are very long. ''' log = logging.getLogger('longreq') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseSIPMessage(msg) # Tweak 1: Such long To value longto = "I have a user name of %s proportion" % ('extreme' * 10) head['To'] = "%s <%s" % (longto, head.get('To').split('<')[1]) head['To'] += ";unknownparam=veryl%sgnvalue" % ('o' * 70) head['To'] += ";longparam%s=shortvalue" % ('name' * 25) head['To'] += "very%sparamwithnovalueatall" % ('long' * 25) # Tweak 2: Such long From Value head['From'] = 'sip:%s@%s' % (('soverylongusernameOOF' * 5), config.RHOST) head['From'] += ';tag=10%s420' % ('789' * 50) head['From'] += ';unknownheadparam%sname=some%shere' % ( ('awkwardlylong' * 10), ('verylong' * 10)) head['From'] += 'paramless%s' % ('value' * 10) # Tweak 3: add call id head['Call-ID'] = 'longreq.one%slongcallidhere' % ('damnlong' * 10) # Tweak 4: add contact head['Contact'] = '<sip:%s@%s>' % (('toolongtohandle' * 10), config.RHOST) # Tweak 5: add unknown value head['Unknown-L%sng-Field' % ('o' * 75)] = '%s;%s=%s' % ('unknown-%s-value' % ('long' * 20), 'unknown-%s-parameter-name' % ('long' * 20), 'unknown-%s-parameter-value' % ('long' * 20)) # Tweak 6: multiply the number of via headers pset = multiHead('Via', permuteasdict=True, singlestr=False) # Merging both the dicts together try: newhead = {**pset, **head} except Exception as e: log.error('Action not supported: %s' % e.__str__()) newhead = pset.copy() newhead.update(head) sipc = 1 for x in newhead.keys(): if not newhead.get(x): newhead[x] = 'SIP/2.0/UDP sip%s.infectedsip.com' % sipc sipc += 1 # incrementing the value properly # Forming the message up back again mg = concatMethodxHeaders(mline, newhead, body=body) return mg
def cseqmatch(): ''' Request Method with CSeq Method Mismatch This request has mismatching values for the method in the start line and the CSeq header field. Any element receiving this request will respond with a 400 Bad Request. ''' log = logging.getLogger('cseqmatch') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify CSeq header head['CSeq'] = '5 INVITE' mg = concatMethodxHeaders(mline, head, body=body) return mg
def bigcode(): ''' Response with Overlarge Status Code This response has a response code larger than 699. An element receiving this response should simply drop it. ''' log = logging.getLogger('bigcode') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseMsg(msg) # Tweak 1: Modify the method line mline = 'SIP/2.0 %s %s' % (random.getrandbits(32), genRandStr(20)) # Forming the request message back up mg = catMetHead(mline, head, body=body) return mg
def spacaddr(): ''' Spaces within address specification This request is malformed, since the addr-spec in the To header field contains spaces. Parsers receiving this request must not break. It is reasonable to reject this request with a 400 Bad Request response. Elements attempting to be liberal may ignore the spaces. ''' log = logging.getLogger('spacaddr') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseMsg(msg) # Tweak 1: add spaces around the To header URL, as simple as that ;) head['To'] = head['To'].replace('<', '< ').replace('>', ' >') mg = catMetHead(mline, head, body=body) return mg
def mfzero(): ''' Zero Value in Max-Forwards Header A proxy should not forward the request and should respond 483 (Too Many Hops). An endpoint should process the request as if the Max- Forwards field value were still positive. ''' log = logging.getLogger('reqpreq') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseMsg(msg) # Tweak 1: Add zero to max-forwards head['Max-Forwards'] = '0' # Forming the request message back up mg = catMetHead(mline, head, body=body) return mg
def lwsuri(): ''' Malformed SIP Request-URI with Embedded LWS This INVITE has illegal LWS within the Request-URI. An element receiving this request should respond with a 400 Bad Request. ''' log = logging.getLogger('lwsuri') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) # Tweak 1: Insert lws after the URI element requri = mline.split(' ')[1] requri += r'; somerandomparamter' mline = mline.replace(mline.split(' ')[1], requri) # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def multicl(): ''' OPTIONS with Multiple Content-Length Values If this request appeared over UDP, so the remainder of the datagram can simply be discarded. If a request like this arrives over TCP, the framing error is not recoverable, and the connection should be closed. ''' log = logging.getLogger('multicl') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Add multiple content-length values head['content-length'] = random.getrandbits(6) # Recompiling our message mg = concatMethodxHeaders(mline, head, body=body) return mg
def balquote(): ''' Unterminated Quoted String in Display Names This is a request with an unterminated quote in the display name of the To field. An element receiving this request should return a 400 Bad Request error. ''' log = logging.getLogger('balquote') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) # Tweak 1: Remove second quote in the to and from headers head['From'] = ''.join(head.get('From').rsplit('"', 1)) head['To'] = ''.join(head.get('To').rsplit('"', 1)) # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def noreason(): ''' Empty Reason Phrase This well-formed response contains no reason phrase. A parser must accept this message. The space character after the reason code is required. If it were not present, this message could be rejected as invalid (a liberal receiver would accept it anyway). ''' log = logging.getLogger('noreason') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) # Tweak 1: Modify the header of the message # We are using a \x20 char to form the remaining mline = 'SIP/2.0 100%s' % bytearray.fromhex('20').decode('utf-8') # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def clerr(): ''' Content Length Larger Than Message This is a request message with a Content Length that is larger than the actual length of the body. When sent over UDP (as this message ostensibly was), the receiving element should respond with a 400 Bad Request error. ''' log = logging.getLogger('clerr') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseMsg(msg) # Tweak 1: Modify the content length header head['Content-Length'] = '%s' % 9999 # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def negcl(): ''' Negative Content-Length This request has a negative value for Content-Length. An element receiving this message should respond with an error. This request appeared over UDP, so the remainder of the datagram can simply be discarded. ''' log = logging.getLogger('negcl') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify the content length header head['Content-Length'] = '-%s' % random.getrandbits(10) # Forming the message up back again mg = concatMethodxHeaders(mline, head, body=body) return mg
def unkproto(): ''' Unknown Protocol Version To an element implementing RFC 3261, this request is malformed due to its high version number. The element should respond to the request with a 505 Version Not Supported error. ''' log = logging.getLogger('unkproto') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Change protocol version mline = mline.replace('SIP/2.0', 'SIP/7.0') head['Via'] = head['Via'].replace('SIP/2.0/UDP', 'SIP/7.0/UDP') mg = concatMethodxHeaders(mline, head, body=body) return mg
def lwsdp(): ''' Message with No LWS between Display Name and < This OPTIONS request is not valid per the grammar in RFC 3261 since there is no LWS between the token in the display name and < in the From header field value. This has been identified as a specification bug that will be removed when RFC 3261 is revised. Elements should accept this request as well formed. ''' log = logging.getLogger('lwsdp') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseMsg(msg) # Tweak 1: Remove LWS between from and to head['From'] = head.get('From').replace(' ', '') head['To'] = head.get('To').replace(' ', '') # Forming the message up back again mg = catMetHead(mline, head, body=body) return mg
def cparam2(): ''' REGISTER with a URL in Contact Header Parameter This register request contains a contact where the URI has an unknown parameter. The register should succeed, and a subsequent retrieval of the registration must include "unknownparam" as a url-parameter. ''' log = logging.getLogger('cparam2') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseSIPMessage(msg) # Tweak 1: Add an unknwown param to contact header head['Contact'] += ';unknownparam' # Tweak 2: Add the </> to make a complete URL head['Contact'] = '<%s>' % head['Contact'] # Forming the request message back up mg = concatMethodxHeaders(mline, head, body=body) return mg