Taras,
On Tue, May 19, 2009 at 6:27 PM, Taras P. Ivashchenko
<naplan...@gmail.com> wrote:
> Hello, Andres and all!
>
>> Hi! How are you? I hope you're well,
> Thanks, I'm in the mood for coding =)
> And you?
>
>> I've been offline for a week or so, and I saw that you commited
>> some changes to your branch. Could you please make a summary of your
>> changes (two lines) for me? I'll be able to download and read the code
>> tomorrow, or maybe on Wendsday :(
>
> For the first I made some clean-up of GUI:
> - in history tab added "Clean" button for viewing all entries
I think that if the user hasn't supplied a search string, the "clear
button" should be "clicked" after every request is sent to the
browser. This way, we'll get always an updated list of requests there.
Also, if the user is filtering with a search, the "Find" button should
be "clicked" after each request is sent to the browser.
What do you think about this idea?
> - in main proxy window:
> * moved Send/Drop/Next to the top (it is more usable)
Agree,
> * added status bar for some messages (alert windows are not good)
Ok,
> - in request/response viewer:
> * from splitted request and response panes made 2 tabs: "Request" and
> "Response"
> * from splitted headers and data pane made common "Raw" tab
It would be really cool to be able to edit the headers in the headers
tab (only on the request being intercepted).
> * rednered response now also in tab
This is nice, but in the past brought some problems like "stack
overflows" and wicked things. But lets try it again, I really think
that we need the rendered view.
> * added draft for "Headers" tab
>
> Screenshots: http://picasaweb.google.ru/naplanetu/W3AF
As usual, EXCELLENT work. I'll never get tired of saying it.
> Todo:
> - headers and params tabs with ability of edit/delete/add/up/down items
Ok,
> - more informative history list
> - code clean-up and first stable point
What about adding the "Options" tab just like in burp suite? I think
that that tab is one of the most important ones, and we'll be able to
do *really interesting* things with it,
> - w3af plugin integration
I think that this will be pretty easy, we just need a button that when
clicked displays a menu with all the plugins from the audit and grep
types in a small tree, and when the user clicks over the plugin name,
the plugin is run with the request/response as a parameter.
> - hhhmmm, as I think we need to clean-up/rewrite backend for sqlite
> (core/data/db/persist.py).
> May be it will be some type of ORM or something like it.
Hmmm, I tried using an ORM... but it never made 100% sense to me.
We'll discuss this later =)
> - code clean-up and second stable point
Ok,
> - HEX editing? 0_o
I'm attaching a hex editor that I was trying to do some time ago. It
is based on some code I found on the internet. I think it's 100%
usable and in the future we'll be able to modify it a little bit in
order to get a fully functional hex editor in gtk.
Cheers,
> --
> Taras P. Ivashchenko <naplan...@gmail.com>
>
--
Andrés Riancho
Founder, Bonsai - Information Security
http://www.bonsai-sec.com/
http://w3af.sf.net/
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2008 Adriano Monteiro Marques
#
# Author: Francesco Piccinno <stack....@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import gtk
import pango
import gobject
class BaseText(gtk.TextView):
__gtype_name__ = "BaseText"
def __init__(self, parent):
self.buffer = gtk.TextBuffer(parent.table)
gtk.TextView.__init__(self, self.buffer)
self._parent = parent
self.modify_font(pango.FontDescription(parent.font))
# Be read only by default
self.set_editable(False)
def set_hexview_widget( self, hv_widget ):
self._hv_widget = hv_widget
gobject.type_register(BaseText)
class OffsetText(BaseText):
def __init__(self, parent):
BaseText.__init__(self, parent)
self.off_len = 1
self.connect('button-press-event', self.__on_button_press)
self.connect('size-request', self.__on_size_request)
self.connect('realize', self.__on_realize)
self.buffer.connect('changed', self.__on_change)
self.set_cursor_visible(False)
def __on_change( self, text_buffer ):
# print text_buffer
pass
def __on_button_press(self, widget, evt):
return True
def __on_realize(self, widget):
self.modify_base(gtk.STATE_NORMAL, self.style.dark[gtk.STATE_NORMAL])
def render(self, txt):
self.buffer.set_text('')
bpl = self._parent.bpl
tot_lines = int(len(txt) / bpl)
if len(txt) % bpl != 0:
tot_lines += 1
self.off_len = len(str(tot_lines)) + 1
output = []
for i in xrange(tot_lines):
output.append(("%0" + str(self.off_len) + "d") % i)
if output:
self.buffer.insert_with_tags(
self.buffer.get_end_iter(),
"\n".join(output),
self._parent.tag_offset
)
def __on_size_request(self, widget, alloc):
ctx = self.get_pango_context()
font = ctx.load_font(pango.FontDescription(self._parent.font))
metric = font.get_metrics(ctx.get_language())
w = pango.PIXELS(metric.get_approximate_char_width()) * (self.off_len + 1)
w += 2
if alloc.width < w:
alloc.width = w
class AsciiText(BaseText):
_printable = """0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?...@[\]^_`{|}~"""
def __init__(self, parent):
BaseText.__init__(self, parent)
self.connect('size-request', self.__on_size_request)
self.buffer.connect('changed', self.__on_change)
self.prev_start = None
self.prev_end = None
self._current_text = None
self._disable_onchange = True
def __on_change( self, text_buffer ):
# I'm going to check where the pointer is,
# and then add that to the self._current_text (in the correct position)
# and finally call set_payload() of the HexView
if not self._disable_onchange:
new_text = self._current_text
# Get the added char and the offset
iter = self.buffer.get_iter_at_mark( self.buffer.get_insert() )
iter.backward_char()
added_char = iter.get_char()
offset = iter.get_offset()
iter.forward_char()
# I don't know why, but I have to mangle the offset a little bit...
line = iter.get_line()
offset = offset - line
new_text = new_text[:offset] + added_char + new_text[offset:]
# Disable myself!
self._disable_onchange = True
self._hv_widget.set_payload( new_text )
iter = self.buffer.get_start_iter()
iter.set_offset(0)
self._disable_onchange = False
def render(self, txt):
self._current_text = txt
self.buffer.set_text('')
bpl = self._parent.bpl
tot_lines = len(txt) / bpl
if len(txt) % bpl != 0:
tot_lines += 1
output = []
convert = lambda i: "".join(
map(lambda x: (x in AsciiText._printable) and (x) or ('.'), list(i)))
for i in xrange(tot_lines):
to_fill = 0
if i * bpl + bpl > len(txt):
to_fill = (i * bpl) + bpl - len(txt)
output.append(
convert(txt[i * bpl:])
)
else:
output.append(
convert(txt[i * bpl:(i * bpl) + bpl])
)
if output:
self._disable_onchange = True
self.buffer.insert_with_tags(
self.buffer.get_end_iter(),
"\n".join(output),
self._parent.tag_ascii
)
self._disable_onchange = False
def __on_size_request(self, widget, alloc):
ctx = self.get_pango_context()
font = ctx.load_font(pango.FontDescription(self._parent.font))
metric = font.get_metrics(ctx.get_language())
w = pango.PIXELS(metric.get_approximate_char_width()) * self._parent.bpl
w += 2
if alloc.width < w:
alloc.width = w
def select_blocks(self, start=None, end=None):
if self.prev_start and self.prev_end and self.prev_start != self.prev_end:
self.buffer.remove_tag(self._parent.tag_sec_sel, self.prev_start, self.prev_end)
if not start and not end:
return
start_iter = self.buffer.get_iter_at_line(start / self._parent.bpl)
start_iter.forward_chars(start % self._parent.bpl)
end_iter = self.buffer.get_iter_at_line(end / self._parent.bpl)
end_iter.forward_chars(end % self._parent.bpl)
self.buffer.apply_tag(self._parent.tag_sec_sel, start_iter, end_iter)
self.prev_start, self.prev_end = start_iter, end_iter
class HexText(BaseText):
def __init__(self, parent):
BaseText.__init__(self, parent)
self.connect('size-request', self.__on_size_request)
self.connect('realize', self.__on_realize)
self.buffer.connect('changed', self.__on_change)
self.prev_start = None
self.prev_end = None
def __on_change( self, text_buffer ):
# print text_buffer
pass
def __on_realize(self, widget):
self.modify_base(gtk.STATE_NORMAL, self.style.mid[gtk.STATE_NORMAL])
def render(self, txt):
self.buffer.set_text('')
bpl = self._parent.bpl
tot_lines = int(len(txt) / bpl)
if len(txt) % bpl != 0:
tot_lines += 1
output = []
convert = lambda x: (len(x) == 1) and ("0%s" % x) or (x)
for i in xrange(tot_lines):
to_fill = 0
if i * bpl + bpl > len(txt):
to_fill = (i * bpl) + bpl - len(txt)
output.append(
" ".join(map(lambda x: convert(str(hex(ord(x)))[2:]), txt[i * bpl:]))
)
else:
output.append(
" ".join(map(lambda x: convert(str(hex(ord(x)))[2:]), txt[i * bpl:(i * bpl) + bpl]))
)
if output:
self.buffer.insert_with_tags(
self.buffer.get_end_iter(),
"\n".join(output).upper(),
self._parent.tag_hex
)
def __on_size_request(self, widget, alloc):
ctx = self.get_pango_context()
font = ctx.load_font(pango.FontDescription(self._parent.font))
metric = font.get_metrics(ctx.get_language())
w = pango.PIXELS(metric.get_approximate_char_width()) * (self._parent.bpl * 3 - 1)
w += 2
if alloc.width < w:
alloc.width = w
def select_blocks(self, start=None, end=None):
if self.prev_start and self.prev_end and self.prev_start != self.prev_end:
self.buffer.remove_tag(self._parent.tag_sec_sel, self.prev_start, self.prev_end)
if not start and not end:
return
start_iter = self.buffer.get_iter_at_line(start / self._parent.bpl)
start_iter.forward_chars(3 * (start % self._parent.bpl))
end_iter = self.buffer.get_iter_at_line(end / self._parent.bpl)
end_iter.forward_chars(3 * (end % self._parent.bpl) - 1)
self.buffer.apply_tag(self._parent.tag_sec_sel, start_iter, end_iter)
self.prev_start, self.prev_end = start_iter, end_iter
class HexView(gtk.HBox):
__gtype_name__ = "HexView"
def __init__(self):
gtk.HBox.__init__(self, False, 4)
self.set_border_width(4)
self.table = gtk.TextTagTable()
self.tag_offset = gtk.TextTag('hex-o-view') # offset view
self.tag_hex = gtk.TextTag('hex-x-view') # hex view
self.tag_ascii = gtk.TextTag('hex-a-view') # ascii view
self.tag_sec_sel = gtk.TextTag('hex-s-selection') # secondary selection
self.table.add(self.tag_offset)
self.table.add(self.tag_hex)
self.table.add(self.tag_ascii)
self.table.add(self.tag_sec_sel)
self._bpl = 16
self._font = "Monospace 10"
self._payload = ""
vadj, hadj = gtk.Adjustment(), gtk.Adjustment()
self.vscroll = gtk.VScrollbar(vadj)
self.offset_text = OffsetText(self)
self.hex_text = HexText(self)
self.ascii_text = AsciiText(self)
self.offset_text.set_scroll_adjustments(hadj, vadj)
self.hex_text.set_scroll_adjustments(hadj, vadj)
self.ascii_text.set_scroll_adjustments(hadj, vadj)
self.hex_text.buffer.connect('mark-set', self.__on_hex_change)
self.ascii_text.buffer.connect('mark-set', self.__on_ascii_change)
self.hex_text.connect('populate-popup', self.__on_menu_popup)
self.ascii_text.connect('populate-popup', self.__on_menu_popup)
def scroll(widget):
widget.set_size_request(-1, 80)
frame = gtk.Frame()
frame.set_shadow_type(gtk.SHADOW_IN)
frame.add(widget)
return frame
# The different view have to be able to communicate with the "father"
# hexview to change the other views when one is edited:
self.hex_text.set_hexview_widget( self )
self.ascii_text.set_hexview_widget( self )
self.pack_start(scroll(self.offset_text), False, False)
self.pack_start(scroll(self.hex_text), False, False)
self.pack_start(scroll(self.ascii_text), False, False)
self.pack_end(self.vscroll, False, False)
def do_realize(self):
gtk.HBox.do_realize(self)
# Offset view
self.tag_offset.set_property('weight', pango.WEIGHT_BOLD)
# Hex View
self.tag_hex.set_property(
'background-gdk',
self.style.mid[gtk.STATE_NORMAL]
)
# Selection tags
self.tag_sec_sel.set_property(
'background-gdk',
self.style.text_aa[gtk.STATE_NORMAL]
)
def __on_menu_popup(self, widget, menu):
item = gtk.SeparatorMenuItem()
item.show()
menu.append(item)
action = gtk.Action('', 'Copy from both', '', gtk.STOCK_COPY)
item = action.create_menu_item()
item.connect('activate', self.__on_copy_from_both)
menu.append(item)
def __on_copy_from_both(self, widget):
if self.hex_text.buffer.get_selection_bounds():
# Hex active
start, end = self.hex_text.buffer.get_selection_bounds()
txt = self.hex_text.buffer.get_text(start, end).replace("\n", " ")
hex_s = filter(lambda x: len(x) == 2, txt.split(" "))
ascii = map(lambda x: chr(int(x, 16)), hex_s)
extend = self.bpl - len(hex_s) % self.bpl
hex_s.extend([" "] * extend)
ascii.extend([" "] * extend)
output = ""
for i in xrange(len(hex_s) / self.bpl):
output += "%s %s\n" % (
" ".join(hex_s[i * self.bpl:(i * self.bpl) + self.bpl]),
"".join(ascii[i * self.bpl:(i * self.bpl) + self.bpl])
)
elif self.ascii_text.buffer.get_selection_bounds():
# Ascii active
start, end = self.ascii_text.buffer.get_selection_bounds()
ascii = list(self.ascii_text.buffer.get_text(start, end).replace("\n", ""))
hex_s = map(lambda x: str(hex(ord(x)))[2:], ascii)
extend = self.bpl - len(ascii) % self.bpl
hex_s.extend([" "] * extend)
ascii.extend([" "] * extend)
output = ""
for i in xrange(len(hex_s) / self.bpl):
output += "%s %s\n" % (
" ".join(hex_s[i * self.bpl:i * self.bpl + self.bpl]),
"".join(ascii[i * self.bpl:i * self.bpl + self.bpl])
)
def __on_hex_change(self, buffer, iter, mark):
if not self.hex_text.buffer.get_selection_bounds():
self.ascii_text.select_blocks() # Deselect
return
start, end = buffer.get_selection_bounds()
if start.get_line() == end.get_line():
tmp = buffer.get_iter_at_line(start.get_line())
txt = buffer.get_text(tmp, start)
s_off = len(filter(lambda x: x != '', txt.split(" ")))
txt = buffer.get_text(start, end)
e_off = len(filter(lambda x: len(x) == 2, txt.split(" ")))
self.ascii_text.select_blocks(
(self.bpl * start.get_line()) + s_off,
(self.bpl * start.get_line()) + s_off + e_off
)
else:
tmp = buffer.get_iter_at_line(start.get_line())
txt = buffer.get_text(tmp, start)
s_off = len(filter(lambda x: x != '', txt.split(" ")))
tmp = buffer.get_iter_at_line(end.get_line())
txt = buffer.get_text(tmp, end)
e_off = len(filter(lambda x: len(x) == 2, txt.split(" ")))
self.ascii_text.select_blocks(
(self.bpl * start.get_line()) + s_off,
(self.bpl * end.get_line()) + e_off
)
def __on_ascii_change(self, buffer, iter, mark):
if not self.ascii_text.buffer.get_selection_bounds():
self.hex_text.select_blocks() # Deselect
return
start, end = self.ascii_text.buffer.get_selection_bounds()
self.hex_text.select_blocks(
(self.bpl * start.get_line()) + start.get_line_index(),
(self.bpl * end.get_line()) + end.get_line_index()
)
def select_block(self, offset, len, ascii=True):
"""
Select a block of data in the HexView
@param offset the offset byte
@param len the lenght of selection
@param ascii True to set primary selection on ASCII otherwise on HEX
"""
start = offset
end = offset + len
# We need to add the \n characters one for each line
start += start / self._bpl
end += end / self._bpl
if start > end:
start, end = end, start
if ascii:
# We need to get a fucking iter!
buffer = self.ascii_text.get_buffer()
start_iter = buffer.get_iter_at_offset(start)
end_iter = buffer.get_iter_at_offset(end)
buffer.select_range(end_iter, start_iter)
def get_payload(self):
return self._payload
def set_payload(self, val):
self._payload = val
for view in (self.offset_text, self.hex_text, self.ascii_text):
# Invalidate previous iters
if hasattr(view, 'prev_start'):
view.prev_start = None
if hasattr(view, 'prev_end'):
view.prev_end = None
view.render(self._payload)
def set_editable( self, value ):
'''
@value: If True, the HexView is editable by the user.
'''
for view in (self.hex_text, self.ascii_text):
view.set_editable( value )
def get_font(self):
return self._font
def modify_font(self, val):
try:
desc = pango.FontDescription(val)
self._font = val
for view in (self.offset_text, self.hex_text, self.ascii_text):
view.modify_font(desc)
except Exception:
pass
def get_bpl(self):
return self._bpl
def set_bpl(self, val):
self._bpl = val
# Redraw!
self.payload = self.payload
payload = property(get_payload, set_payload)
font = property(get_font, modify_font)
bpl = property(get_bpl, set_bpl)
gobject.type_register(HexView)
if __name__ == "__main__":
w = gtk.Window()
view = HexView()
view.set_payload("Woo welcome this is a simple read/only"
" HexView widget for PacketManipulator")
# This toogles read only mode on/off
view.set_editable(True)
w.add(view)
w.show_all()
w.connect('delete-event', lambda *w: gtk.main_quit())
gtk.main()
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables
unlimited royalty-free distribution of the report engine
for externally facing server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
W3af-develop mailing list
W3af-develop@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/w3af-develop