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 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 makeRequest(method, bsbody='', contentlength=None): ''' Build up the SIP request properly from scratch ''' headers = DEF_HSET extension = DEF_EXT branch = BRANCH body = '' contenttype = None if not SRC_HOST: srchost = socket.gethostbyname(socket.gethostname()) dsthost = IP # if IP else validateHost(RHOST) if 'invite' in method.lower(): body = INVITE_BODY body = body.replace('x.x.x.x', srchost).replace('y.y.y.y', dsthost) if bsbody: body = bsbody if extension is None or method.upper() == 'REGISTER': uri = 'sip:%s' % dsthost else: uri = 'sip:%s@%s' % (extension, dsthost) if SPOOF_UA: headers['User-Agent'] = randUASelect() else: headers['User-Agent'] = USER_AGENT if not BRANCH: branch = '%s' % random.getrandbits(32) else: srchost = SRC_HOST headers['Via'] = 'SIP/2.0/UDP %s:%s;branch=z9hG4bK-%s;rport' % ( srchost, LPORT, branch) headers['Max-Forwards'] = 70 if not (TO_ADDR or FROM_ADDR): senderext = genRandStr(5) headers['To'] = '"%s" <sip:%s@%s>' % (DEF_EXT, DEF_EXT, RHOST) headers['From'] = '"siptorch" <sip:%s@%s>' % (senderext, RHOST) # If method is register, we need to modify To, From header fields if method == 'REGISTER': headers['From'] = '"%s" <sip:%s@%s>' % (extension, extension, RHOST) headers['To'] = headers['From'] if method.lower() != 'ack': if FROM_TAG is None: headers['From'] += ';tag=' + str(random.getrandbits(90)) else: headers['From'] += ';tag=' + FROM_TAG if not STATIC_CID: headers["Call-ID"] = random.getrandbits(80) headers['CSeq'] = '%s %s' % (CSEQ, method) headers['Content-Length'] = len(body) if 'register' not in method.lower(): headers['Contact'] = '<sip:%s@%s>' % (senderext, RHOST) if CONTENT_TYPE is not None and len(body) > 0: contenttype = CONTENT_TYPE if contenttype is not None: headers['Content-Type'] = contenttype r = '%s %s SIP/2.0\r\n' % (method, uri) reformedmsg = catMetHead(r, headers, body=body) return reformedmsg
def reqpreq(): ''' Require & Proxy-Require Implementation Stress This request tests proper implementation of SIP's Proxy-Require and Require extension mechanisms. Any element receiving this request will respond with a 420 Bad Extension response, containing an Unsupported header field listing these features from either the Require or Proxy-Require header field, depending on the role in which the element is responding. ''' log = logging.getLogger('reqpreq') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('OPTIONS') mline, head, body = parseSIPMessage(msg) # Tweak 1: Add Require & Proxy-Require fields head['Require'] = '%s, %s' % (genRandStr(10), random.getrandbits(32)) head['Proxy-Require'] = '%s, %s' % (genRandStr(10), genRandStr(20)) # Forming the request message back up 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 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 invsdp(): ''' Invalid/Unacceptable Accept Offering This request indicates that the response must contain a body in an unknown type. In particular, since the Accept header field does not contain application/sdp, the response may not contain an SDP body. The recipient of this request could respond with a 406 Not Acceptable, with a Warning/399 indicating that a response cannot be formulated in the formats offered in the Accept header field. It is also appropriate to respond with a 400 Bad Request, since all SIP User-Agents (UAs) supporting INVITE are required to support application/sdp. ''' log = logging.getLogger('invsdp') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('REGISTER') mline, head, body = parseMsg(msg) # Tweak 1: Invalid Accept offering head['Accept'] = 'text/%s' % genRandStr(7) # Forming the request message back up mg = catMetHead(mline, head, body=body) return mg
def invct(): ''' Unknown/Invalid Content Type This INVITE request contains a body of unknown type. It is syntactically valid. A parser must not fail when receiving it. A proxy receiving this request would process it just as it would any other INVITE. An endpoint receiving this request would reject it with a 415 Unsupported Media Type error. ''' log = logging.getLogger('invct') log.info('Testing module: %s' % module_info['test']) msg = buildreq.makeRequest('INVITE') mline, head, body = parseSIPMessage(msg) # Tweak 1: Modify the content type head['Content-Type'] = 'application/%s' % genRandStr(10) # Tweak 2: Modify the body body = '<audio>\r\n <pcmu port="443"/>\r\n</audio>' # Tweak 3: Modify the content-length head['Content-Length'] = '%s' % len(body) # Forming the request message back up mg = concatMethodxHeaders(mline, head, body=body) return mg
def randUASelect(randstr=False, length=30): if randstr: return genRandStr(length, allow_digits=True) else: return random.choice(ualist)