def __init__(self, netmanager, parent = None): QWidget.__init__(self, parent) self.netmanager = netmanager self.current_request_id = 0 self.smartview = SmartView(self) self.smartview.hide() self.requestview = TamperTreeWidget() self.requestview.setRootIsDecorated(False) self.requestview.setAlternatingRowColors(True) self.requestview.setSortingEnabled(False) self.requestview.setEditTriggers(QAbstractItemView.DoubleClicked) self.requestview.setHeaderLabels(['HTTP Request Header', 'Value']) self.requestview.resizeColumnToContents(0) self.requestview.setWordWrap(True) QObject.connect(self.requestview, SIGNAL("itemChanged(QTreeWidgetItem *, int)"), self.requestChangedItem_Slot) QObject.connect(self.requestview, SIGNAL("addRowTreeWidget"), self.addRowTreeWidget_Slot) QObject.connect(self.requestview, SIGNAL("duplicateRowTreeWidget"), self.duplicateRowTreeWidget_Slot) QObject.connect(self.requestview, SIGNAL("deleteRowTreeWidget"), self.deleteRowTreeWidget_Slot) self.responseview = QTreeWidget() self.responseview.setRootIsDecorated(False) self.responseview.setAlternatingRowColors(True) self.responseview.setSortingEnabled(False) self.responseview.setHeaderLabels(['HTTP Response Header', 'Value']) self.responseview.resizeColumnToContents(0) self.gbox = QGroupBox("&HTTP Request") self.refresh_button = QPushButton("Refresh") self.refresh_button.setEnabled(False) QObject.connect(self.refresh_button, SIGNAL("pressed()"), self.refreshViews_Slot) self.response_button = QPushButton("HTTP response body") QObject.connect(self.response_button, SIGNAL("pressed()"), self.viewResponse_Slot) self.replay_button = QPushButton("Make request") QObject.connect(self.replay_button, SIGNAL("pressed()"), self.replayRequest_Slot) self.export_button = QPushButton("Export as...") QObject.connect(self.replay_button, SIGNAL("pressed()"), self.exportRequest_Slot) self.addTestCases_button = QPushButton("Add to test cases") QObject.connect(self.addTestCases_button, SIGNAL("pressed()"), self.addTestCaseRequest_Slot) self.addFinding_button = QPushButton("Add to findings") QObject.connect(self.addFinding_button, SIGNAL("pressed()"), self.addFindingRequest_Slot) vlayout = QVBoxLayout() vlayout.addWidget(self.response_button) vlayout.addWidget(self.refresh_button) vlayout.addWidget(self.replay_button) vlayout.addWidget(self.export_button) vlayout.addWidget(self.addTestCases_button) vlayout.addWidget(self.addFinding_button) self.gbox.setLayout(vlayout) layout = QHBoxLayout() layout.addWidget(self.gbox) layout.addWidget(self.requestview) layout.addWidget(self.responseview) self.setLayout(layout)
class TamperingData(QWidget): """ tampering data widget in dock """ def __init__(self, netmanager, parent = None): QWidget.__init__(self, parent) self.netmanager = netmanager self.current_request_id = 0 self.smartview = SmartView(self) self.smartview.hide() self.requestview = TamperTreeWidget() self.requestview.setRootIsDecorated(False) self.requestview.setAlternatingRowColors(True) self.requestview.setSortingEnabled(False) self.requestview.setEditTriggers(QAbstractItemView.DoubleClicked) self.requestview.setHeaderLabels(['HTTP Request Header', 'Value']) self.requestview.resizeColumnToContents(0) self.requestview.setWordWrap(True) QObject.connect(self.requestview, SIGNAL("itemChanged(QTreeWidgetItem *, int)"), self.requestChangedItem_Slot) QObject.connect(self.requestview, SIGNAL("addRowTreeWidget"), self.addRowTreeWidget_Slot) QObject.connect(self.requestview, SIGNAL("duplicateRowTreeWidget"), self.duplicateRowTreeWidget_Slot) QObject.connect(self.requestview, SIGNAL("deleteRowTreeWidget"), self.deleteRowTreeWidget_Slot) self.responseview = QTreeWidget() self.responseview.setRootIsDecorated(False) self.responseview.setAlternatingRowColors(True) self.responseview.setSortingEnabled(False) self.responseview.setHeaderLabels(['HTTP Response Header', 'Value']) self.responseview.resizeColumnToContents(0) self.gbox = QGroupBox("&HTTP Request") self.refresh_button = QPushButton("Refresh") self.refresh_button.setEnabled(False) QObject.connect(self.refresh_button, SIGNAL("pressed()"), self.refreshViews_Slot) self.response_button = QPushButton("HTTP response body") QObject.connect(self.response_button, SIGNAL("pressed()"), self.viewResponse_Slot) self.replay_button = QPushButton("Make request") QObject.connect(self.replay_button, SIGNAL("pressed()"), self.replayRequest_Slot) self.export_button = QPushButton("Export as...") QObject.connect(self.replay_button, SIGNAL("pressed()"), self.exportRequest_Slot) self.addTestCases_button = QPushButton("Add to test cases") QObject.connect(self.addTestCases_button, SIGNAL("pressed()"), self.addTestCaseRequest_Slot) self.addFinding_button = QPushButton("Add to findings") QObject.connect(self.addFinding_button, SIGNAL("pressed()"), self.addFindingRequest_Slot) vlayout = QVBoxLayout() vlayout.addWidget(self.response_button) vlayout.addWidget(self.refresh_button) vlayout.addWidget(self.replay_button) vlayout.addWidget(self.export_button) vlayout.addWidget(self.addTestCases_button) vlayout.addWidget(self.addFinding_button) self.gbox.setLayout(vlayout) layout = QHBoxLayout() layout.addWidget(self.gbox) layout.addWidget(self.requestview) layout.addWidget(self.responseview) self.setLayout(layout) def addRowTreeWidget_Slot(self, item): p = item.parent() new_item = QTreeWidgetItem() new_item.setText(0, "") new_item.setText(1, "") new_item.setFlags(new_item.flags() | Qt.ItemIsEditable) if p: p.addChild(new_item) else: self.requestview.invisibleRootItem().addChild(new_item) def duplicateRowTreeWidget_Slot(self, item): p = item.parent() new_item = QTreeWidgetItem() new_item.setText(0, item.text(0)) new_item.setText(1, item.text(1)) new_item.setFlags(new_item.flags() | Qt.ItemIsEditable) if p: p.addChild(new_item) else: self.requestview.invisibleRootItem().addChild(new_item) def deleteRowTreeWidget_Slot(self, item): self.requestview.invisibleRootItem().removeChild(item) def viewResponse_Slot(self): # create popup with smart document preview if 0 < self.current_request_id: self.smartview.setWindowFlags(Qt.Window) content, content_type = self.netmanager.getResponseContent(self.current_request_id) if content: self.smartview.show() self.smartview.setContent(content, content_type) def retrieveHeader(self): headers = [] self.requestview def addFindingRequest_Slot(self): if 0 < self.current_request_id: self.emit(SIGNAL('addRequestIDtoFindings_Signal'), [self.current_request_id]) def addTestCaseRequest_Slot(self): if 0 < self.current_request_id: self.emit(SIGNAL('addRequestIDtoTestCases_Signal'), [self.current_request_id]) def exportRequest_Slot(self): # if modified, send to tamper.create_request to forge the new request # else, send the request_id for a simple replay based on historical requests if self.refresh_button.isEnabled(): # retrieve data nrequest = {'method' : None, 'url' : None, 'headers' : [], 'cookies' : [], 'post' : []} request_iter = QTreeWidgetIterPy(self.requestview) firstiter, state = True, "headers" for elmt in request_iter: if firstiter: nrequest['method'] = elmt.text(0) nrequest['url'] = elmt.text(1) firstiter = False else: # state: headers -> cookies -> post if "-" == elmt.text(0): continue if "headers" == state: if "Cookies" == elmt.text(0): state = "cookies" continue elif "POST data" == elmt.text(0): state = "post" continue elif "cookies" == state: if "POST data" == elmt.text(0): state = "post" continue nrequest[state].append((elmt.text(0), elmt.text(1))) nrequest[state].append((elmt.text(0), elmt.text(1))) self.emit(SIGNAL('createHTTPRequest'), nrequest) else: self.emit(SIGNAL('createHTTPRequest'), self.current_request_id) def replayRequest_Slot(self): request_headers = self.retrieveHeader() def requestChangedItem_Slot(self, item, col): self.refresh_button.setEnabled(True) def refreshViews_Slot(self): self.setRequestResponse_Slot(self.current_request_id) self.refresh_button.setEnabled(False) @staticmethod def __create_treeitem(name, value, icon = None): if not isinstance(name, QString): name = QString(name) if not isinstance(value, QString): value = QString(value) item = QTreeWidgetItem() item.setText(0, name) if icon: item.setIcon(0, icon) item.setText(1, value) item.setFlags(item.flags() | Qt.ItemIsEditable) return item @staticmethod def __create_treeseparator(name): bgColor = QColor(0, 0, 255, 25) if not isinstance(name, QString): name = QString(name) item = QTreeWidgetItem() item.setText(0, name) item.setBackgroundColor(0, bgColor) item.setBackgroundColor(1, bgColor) return item def setRequestResponse_Slot(self, request_id): self.current_request_id = request_id info = self.netmanager.getNetworkHistory(request_id) self.requestview.setUpdatesEnabled(False) self.requestview.clear() # process request item = QTreeWidgetItem() item.setText(0, info['type']) item.setText(1, info['request']['url'].toString(QUrl.StripTrailingSlash)) item.setFlags(item.flags() | Qt.ItemIsEditable) self.requestview.invisibleRootItem().addChild(item) for h in info['request']['headers']: self.requestview.invisibleRootItem().addChild(TamperingData.__create_treeitem(h[0], h[1] if 2 == len(h) else "")) # add Cookies view for request if info['request']['cookies']: cookies = info['request']['cookies'] tree_cookies = TamperingData.__create_treeseparator("Cookies") self.requestview.invisibleRootItem().addChild(tree_cookies) for elmt in cookies: tree_cookies.addChild(TamperingData.__create_treeitem(QString(elmt.name()), QString(elmt.toRawForm()).remove(QString(elmt.name()+' = ')))) self.requestview.expandAll() # add POST data for request if info['request']['content']: post_data = QString(info['request']['content-QByteArray']) tree_post = TamperingData.__create_treeseparator("POST data") self.requestview.invisibleRootItem().addChild(tree_post) postQueryStringURL = QUrl("http://sheep") postQueryStringURL.setEncodedQuery(info['request']['content-QByteArray']) for elmts in postQueryStringURL.queryItems(): tree_post.addChild(TamperingData.__create_treeitem(QString(elmts[0]), elmts[1] if 2 == len(elmts) else "")) self.requestview.expandAll() self.requestview.setUpdatesEnabled(True) self.responseview.setUpdatesEnabled(False) self.responseview.clear() # process request for h in info['response']['headers']: item = QTreeWidgetItem() item.setText(0, QString(h[0])) if 2 == len(h): item.setText(1, QString(h[1])) self.responseview.invisibleRootItem().addChild(item) self.responseview.setUpdatesEnabled(True)