Skip to content

Commit

Permalink
improved tamper options. #issue: Tamper options #5
Browse files Browse the repository at this point in the history
  • Loading branch information
needle-wang committed Jan 28, 2021
1 parent 1c54002 commit 8338147
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 44 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
## sqlmap-gtk
sqlmap GUI, using PyGObject(gtk+3)

support linux, test on Mint 20, kali 2020.4
supports linux, test on Mint 20, kali 2020.4
[sqlmap-wx](https://github.com/needle-wang/sqlmap-wx) on win, which needs to improve.
sqlmap has port to python3.
don't use python2 any more please.
Expand Down Expand Up @@ -34,8 +34,8 @@ don't use python2 any more please.
it works fine.

#### ABOUT
- v0.3.5.1
2021-01-05 13:33:04
- v0.3.5.2
2021-01-29 04:04:35
- use PyGObject(python3-gi + Gtk+3) to recode sqm.py
- thanks to the idea from sqm <https://github.com/kxcode/gui-for-sqlmap>
author: [KINGX](https://github.com/kxcode)(sqm UI using python2 + tkinter)
Expand Down
28 changes: 20 additions & 8 deletions handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,10 @@ def _collect_opts(self):
m._general_area_batch_ckbtn),
self._get_text_only_ckbtn("--wizard",
m._misc_area_wizard_ckbtn),
# self._get_tampers('--tamper=',
# m._tamper_area_tamper_view),
self._get_tampers('--tamper=',
m._tamper_area_tamper_view),
m._tampers_name),
self._get_text_only_ckbtn("--crack",
m._hidden_area_crack_ckbtn),
self._get_text_only_ckbtn("--debug",
Expand Down Expand Up @@ -759,15 +761,25 @@ def _get_http_proxy(self, opt_str):
_port = ':%s' % _port
return "{}{}{}".format(opt_str, _ip, _port)

def _get_tampers(self, opt_str, textview):
_tamper_textbuffer = textview.get_buffer()
def _get_tampers(self, opt_str, tampers):
_checked = []
for _tamper in tampers:
if _tamper.get_active():
_checked.append(_tamper.get_label())

_start = _tamper_textbuffer.get_start_iter()
_end = _tamper_textbuffer.get_end_iter()
_ = _tamper_textbuffer.get_text(_start, _end, False)
_ = ','.join(_.split())
_ = ','.join(_checked)
if _:
return "{}{}".format(opt_str, quote(_))
return "{}{}".format(opt_str, _)

# def _get_tampers(self, opt_str, textview):
# _tamper_textbuffer = textview.get_buffer()

# _start = _tamper_textbuffer.get_start_iter()
# _end = _tamper_textbuffer.get_end_iter()
# _ = _tamper_textbuffer.get_text(_start, _end, False)
# _ = ','.join(_.split())
# if _:
# return "{}{}".format(opt_str, quote(_))

def _get_text_from_scale(self, opt_str, ckbtn, scale):
if ckbtn.get_active():
Expand Down
98 changes: 95 additions & 3 deletions model.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ def __init__(self, language):
self._tech_area_second_req_entry = FileEntry()
self._tech_area_second_req_chooser = btn.new_with_label(_('open'))
# Tamper
self._tamper_frame = Frame.new(_('--tamper'))
self._tamper_area_tamper_view = tv(wrap_mode = g.WrapMode.CHAR)
# self._tamper_frame = Frame.new(_('--tamper'))
# self._tamper_area_tamper_view = tv(wrap_mode = g.WrapMode.CHAR)
# Optimize
self._optimize_frame = Frame.new(_('Optimize'))
self._optimize_area_turn_all_ckbtn = cb(_('-o'))
Expand Down Expand Up @@ -441,7 +441,7 @@ def __init__(self, language):
self._misc_area_results_file_entry = FileEntry()
self._misc_area_results_file_chooser = btn.new_with_label(_('open'))
# Tamper

self._tampers()
# EXECUTION(2)
self._page2_respwan_btn = btn.new_with_label(_('reopen'))
self._page2_right_btn = btn.new_with_label(_('context menu'))
Expand Down Expand Up @@ -477,6 +477,98 @@ def __init__(self, language):
self._page6_tooltips_zh_radio = g.RadioButton.new_from_widget(self._page6_tooltips_en_radio)
self._page6_tooltips_zh_radio.set_label('zh')

def _tampers(self):
self._tampers_name = [
cb('0eunion.py'), cb('apostrophemask.py'), cb('apostrophenullencode.py'),
cb('appendnullbyte.py'), cb('base64encode.py'), cb('between.py'),
cb('binary.py'), cb('bluecoat.py'), cb('chardoubleencode.py'),
cb('charencode.py'), cb('charunicodeencode.py'), cb('charunicodeescape.py'),
cb('commalesslimit.py'), cb('commalessmid.py'), cb('commentbeforeparentheses.py'),
cb('concat2concatws.py'), cb('dunion.py'), cb('equaltolike.py'),
cb('equaltorlike.py'), cb('escapequotes.py'), cb('greatest.py'),
cb('halfversionedmorekeywords.py'), cb('hex2char.py'), cb('htmlencode.py'),
cb('ifnull2casewhenisnull.py'), cb('ifnull2ifisnull.py'), cb('informationschemacomment.py'),
cb('least.py'), cb('lowercase.py'), cb('luanginx.py'),
cb('misunion.py'), cb('modsecurityversioned.py'), cb('modsecurityzeroversioned.py'),
cb('multiplespaces.py'), cb('overlongutf8.py'), cb('overlongutf8more.py'),
cb('percentage.py'), cb('plus2concat.py'), cb('plus2fnconcat.py'),
cb('randomcase.py'), cb('randomcomments.py'), cb('schemasplit.py'),
cb('sleep2getlock.py'), cb('sp_password.py'), cb('space2comment.py'),
cb('space2dash.py'), cb('space2hash.py'), cb('space2morecomment.py'),
cb('space2morehash.py'), cb('space2mssqlblank.py'), cb('space2mssqlhash.py'),
cb('space2mysqlblank.py'), cb('space2mysqldash.py'), cb('space2plus.py'),
cb('space2randomblank.py'), cb('substring2leftright.py'), cb('symboliclogical.py'),
cb('unionalltounion.py'), cb('unmagicquotes.py'), cb('uppercase.py'),
cb('varnish.py'), cb('versionedkeywords.py'), cb('versionedmorekeywords.py'),
cb('xforwardedfor.py'),
]
self._tampers_label = [
label.new(r"Replaces instances of <int> UNION with <int>e0UNION"),
label.new(r"Replaces apostrophe character (') with its UTF-8 full width counterpart (e.g. ' -> %EF%BC%87)"),
label.new(r"Replaces apostrophe character (') with its illegal double unicode counterpart (e.g. ' -> %00%27)"),
label.new(r"Appends (Access) NULL byte character (%00) at the end of payload"),
label.new(r"Base64-encodes all characters in a given payload"),
label.new(r"Replaces greater than operator ('>') with 'NOT BETWEEN 0 AND #' and equals operator ('=') with 'BETWEEN # AND #'"),
label.new(r"Injects keyword binary where possible"),
label.new(r"Replaces space character after SQL statement with a valid random blank character. Afterwards replace character '=' with operator LIKE"),
label.new(r"Double URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %2553%2545%254C%2545%2543%2554)"),
label.new(r"URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %53%45%4C%45%43%54)"),
label.new(r"Unicode-URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %u0053%u0045%u004C%u0045%u0043%u0054)"),
label.new(r"Unicode-escapes non-encoded characters in a given payload (not processing already encoded) (e.g. SELECT -> \u0053\u0045\u004C\u0045\u0043\u0054)"),
label.new(r"Replaces (MySQL) instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' counterpart"),
label.new(r"Replaces (MySQL) instances like 'MID(A, B, C)' with 'MID(A FROM B FOR C)' counterpart"),
label.new(r"Prepends (inline) comment before parentheses (e.g. ( -> /**/()"),
label.new(r"Replaces (MySQL) instances like 'CONCAT(A, B)' with 'CONCAT_WS(MID(CHAR(0), 0, 0), A, B)' counterpart"),
label.new(r"Replaces instances of <int> UNION with <int>DUNION"),
label.new(r"Replaces all occurrences of operator equal ('=') with 'LIKE' counterpart"),
label.new(r"Replaces all occurrences of operator equal ('=') with 'RLIKE' counterpart"),
label.new(r"Slash escape single and double quotes (e.g. ' -> \')"),
label.new(r"Replaces greater than operator ('>') with 'GREATEST' counterpart"),
label.new(r"Adds (MySQL) versioned comment before each keyword"),
label.new(r"Replaces each (MySQL) 0x<hex> encoded string with equivalent CONCAT(CHAR(),...) counterpart"),
label.new(r"HTML encode (using code points) all non-alphanumeric characters (e.g. ' -> &#39;)"),
label.new(r"Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END' counterpart"),
label.new(r"Replaces instances like 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)' counterpart"),
label.new(r"Add an inline comment (/**/) to the end of all occurrences of (MySQL) \"information_schema\" identifier"),
label.new(r"Replaces greater than operator ('>') with 'LEAST' counterpart"),
label.new(r"Replaces each keyword character with lower case value (e.g. SELECT -> select)"),
label.new(r"LUA-Nginx WAFs Bypass (e.g. Cloudflare)"),
label.new(r"Replaces instances of UNION with -.1UNION"),
label.new(r"Embraces complete query with (MySQL) versioned comment"),
label.new(r"Embraces complete query with (MySQL) zero-versioned comment"),
label.new(r"Adds multiple spaces (' ') around SQL keywords"),
label.new(r"Converts all (non-alphanum) characters in a given payload to overlong UTF8 (not processing already encoded) (e.g. ' -> %C0%A7)"),
label.new(r"Converts all characters in a given payload to overlong UTF8 (not processing already encoded) (e.g. SELECT -> %C1%93%C1%85%C1%8C%C1%85%C1%83%C1%94)"),
label.new(r"Adds a percentage sign ('%') infront of each character (e.g. SELECT -> %S%E%L%E%C%T)"),
label.new(r"Replaces plus operator ('+') with (MsSQL) function CONCAT() counterpart"),
label.new(r"Replaces plus operator ('+') with (MsSQL) ODBC function {fn CONCAT()} counterpart"),
label.new(r"Replaces each keyword character with random case value (e.g. SELECT -> SEleCt)"),
label.new(r"Add random inline comments inside SQL keywords (e.g. SELECT -> S/**/E/**/LECT)"),
label.new(r"Splits FROM schema identifiers (e.g. 'testdb.users') with whitespace (e.g. 'testdb 9.e.users')"),
label.new(r"Replaces instances like 'SLEEP(5)' with (e.g.) \"GET_LOCK('ETgP',5)\""),
label.new(r"Appends (MsSQL) function 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs"),
label.new(r"Replaces space character (' ') with comments '/**/'"),
label.new(r"Replaces space character (' ') with a dash comment ('--') followed by a random string and a new line ('\n')"),
label.new(r"Replaces (MySQL) instances of space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')"),
label.new(r"Replaces (MySQL) instances of space character (' ') with comments '/**_**/'"),
label.new(r"Replaces (MySQL) instances of space character (' ') with a pound character ('#') followed by a random string and a new line ('\n')"),
label.new(r"Replaces (MsSQL) instances of space character (' ') with a random blank character from a valid set of alternate characters"),
label.new(r"Replaces space character (' ') with a pound character ('#') followed by a new line ('\n')"),
label.new(r"Replaces (MySQL) instances of space character (' ') with a random blank character from a valid set of alternate characters"),
label.new(r"Replaces space character (' ') with a dash comment ('--') followed by a new line ('\n')"),
label.new(r"Replaces space character (' ') with plus ('+')"),
label.new(r"Replaces space character (' ') with a random blank character from a valid set of alternate characters"),
label.new(r"Replaces PostgreSQL SUBSTRING with LEFT and RIGHT"),
label.new(r"Replaces AND and OR logical operators with their symbolic counterparts (&& and ||)"),
label.new(r"Replaces instances of UNION ALL SELECT with UNION SELECT counterpart"),
label.new(r"Replaces quote character (') with a multi-byte combo %BF%27 together with generic comment at the end (to make it work)"),
label.new(r"Replaces each keyword character with upper case value (e.g. select -> SELECT)"),
label.new(r"Appends a HTTP header 'X-originating-IP' to bypass Varnish Firewall"),
label.new(r"Encloses each non-function keyword with (MySQL) versioned comment"),
label.new(r"Encloses each keyword with (MySQL) versioned comment"),
label.new(r"Append a fake HTTP header 'X-Forwarded-For' (and alike)"),
]

def _(self, s):
return s

Expand Down
52 changes: 38 additions & 14 deletions opts_gtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ def __init__(self, m, handlers):
page1_enumeration = self._build_page1_enumeration()
page1_file = self._build_page1_file()
page1_other = self._build_page1_other()
page1_tamper = self._build_page1_tamper(m)

_ = m._
self.append_page(page1_setting, label.new_with_mnemonic(_('Inject(_Q)')))
self.append_page(page1_request, label.new_with_mnemonic(_('Request(_W)')))
self.append_page(page1_enumeration, label.new_with_mnemonic(_('Enumerate(_E)')))
self.append_page(page1_file, label.new_with_mnemonic(_('File(_R)')))
self.append_page(page1_other, label.new_with_mnemonic(_('Other(_T)')))
self.append_page(page1_tamper, label.new_with_mnemonic(_('Tamper(_Y)')))

def cb_single(self, widget, ckbtn):
if widget.get_active():
Expand Down Expand Up @@ -74,12 +76,12 @@ def _build_page1_setting(self, m):
_row1.pack_start(_tech_area, False, True, 5)

_row2 = Box()
_tamper_area = self._build_page1_setting_tamper(self.m)
# _tamper_area = self._build_page1_setting_tamper(self.m)
_optimize_area = self._build_page1_setting_optimize(self.m)
_general_area = self._build_page1_setting_general(self.m)
_hidden_area = self._build_page1_setting_hidden(self.m)

_row2.pack_start(_tamper_area, False, True, 5)
# _row2.pack_start(_tamper_area, False, True, 5)
_row2.pack_start(_optimize_area, False, True, 5)
_row2.pack_start(_general_area, False, True, 5)
_row2.pack_start(_hidden_area, False, True, 5)
Expand Down Expand Up @@ -257,19 +259,19 @@ def _build_page1_setting_tech(self, m):
m._tech_frame.add(_tech_area_opts)
return m._tech_frame

def _build_page1_setting_tamper(self, m):
'''
frame套box, box再套scroll会出现:
一直按回车出现滚动条后, 光标会下移 直到移出可见区, 原内容不会上移
即内容的显示没有 下滑 滚轮的效果.
'''
_scrolled = g.ScrolledWindow()
_scrolled.set_size_request(300, -1)
_scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS)
_scrolled.add(m._tamper_area_tamper_view)
# def _build_page1_setting_tamper(self, m):
# '''
# frame套box, box再套scroll会出现:
# 一直按回车出现滚动条后, 光标会下移 直到移出可见区, 原内容不会上移
# 即内容的显示没有 下滑 滚轮的效果.
# '''
# _scrolled = g.ScrolledWindow()
# _scrolled.set_size_request(300, -1)
# _scrolled.set_policy(g.PolicyType.NEVER, g.PolicyType.ALWAYS)
# _scrolled.add(m._tamper_area_tamper_view)

m._tamper_frame.add(_scrolled)
return m._tamper_frame
# m._tamper_frame.add(_scrolled)
# return m._tamper_frame

def _build_page1_setting_optimize(self, m):
_boxes = [Box() for _ in range(5)]
Expand Down Expand Up @@ -1077,6 +1079,28 @@ def _build_page1_other_misc(self, m):
m._misc_frame.add(_page1_other_misc_opts)
return m._misc_frame

def _build_page1_tamper(self, m):
grid = g.Grid(row_spacing = 6, margin = 15)

_i = 0 # row number
for name, discribe in dict(zip(m._tampers_name, m._tampers_label)).items():
if _i % 2 != 0:
# stripe style for css
# name.set_name('stripe')
discribe.set_name('stripe')

grid.attach(name, 0, _i, 1, 1)
# grid.attach(discribe, 1, _i, 1, 1)
_ = Box() # resolve that label always be center align...
_.pack_start(discribe, False, True, 0)
grid.attach_next_to(_, name, g.PositionType.RIGHT, 1, 1)
_i += 1

scrolled = g.ScrolledWindow()
scrolled.set_policy(g.PolicyType.AUTOMATIC, g.PolicyType.ALWAYS)
scrolled.add(grid)
return scrolled


def main():
import time
Expand Down
16 changes: 13 additions & 3 deletions session.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ def _save_to_tmp_ckbtn(self):
if isinstance(_tmp_ckbtn, g.CheckButton) and _tmp_ckbtn.get_active():
_checked.append(_i)

if _i == '_tampers_name':
_tampers_name = getattr(self.m, _i)

for _tamper, index in zip(_tampers_name, range(len(_tampers_name))):
if _tamper.get_active():
_checked.append('tamper_{}'.format(index))

# print(_checked)
self._cfg['CheckButton']['checked'] = ','.join(_checked)

def _save_to_tmp_entry(self):
Expand Down Expand Up @@ -137,9 +145,11 @@ def _load_from_tmp_ckbtn(self):
_checked = self._cfg['CheckButton']['checked'].split(',')
for _i in _checked:
if _i: # _i could be ''
# 不去手动改LAST_TMP, self.m就肯定有_i属性了
_tmp_ckbtn = getattr(self.m, _i)
_tmp_ckbtn.set_active(True)
if _i.endswith('_ckbtn'):
_tmp_ckbtn = getattr(self.m, _i)
_tmp_ckbtn.set_active(True)
if _i.startswith('tamper_'):
self.m._tampers_name[int(_i[len('tamper_'):])].set_active(True)
else: # if _checked = [''], then use default
pass
except KeyError as e:
Expand Down
6 changes: 4 additions & 2 deletions sqlmap_gtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ def unselect_all_ckbtn(self, button):
for _i in m._enum_area_opts_ckbtns:
for _j in _i:
_j.set_active(False)
for _i in m._tampers_name:
_i.set_active(False)

def _show_warn(self, button, mesg):
if button.get_active():
Expand Down Expand Up @@ -619,8 +621,8 @@ def _build_page6(self):
_url_api = 'https://lazka.github.io/pgi-docs/Gtk-3.0/'
_url_idea = 'https://github.com/kxcode'
_about_str = f'''
1. <a href="{_url_self}" title = "{_url_self}">Website</a> VERSION: 0.3.5.1
2021-01-05 13:33:04
1. <a href="{_url_self}" title = "{_url_self}">Website</a> VERSION: 0.3.5.2
2021-01-29 04:04:35
required: python3.6+, gtk+3.20 above,
python3-gi, requests, sqlmap\n
2. use PyGObject(python3-gi + Gtk+3) to recode sqm.py
Expand Down
4 changes: 4 additions & 0 deletions static/css.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ button:active {
border-style: inset;
}

#stripe {
background-color: #eee;
}

10 changes: 5 additions & 5 deletions tooltips.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,11 +266,11 @@ def set_all_tooltips(self, m):
'if you controlled a DNS server, check it to speed up the process of data retrieval',
m._tech_area_dns_ckbtn,
m._tech_area_dns_entry)
self._set_tooltip('sqlmap itself does no obfuscation of the payload sent,\n'
'except for strings between single quotes replaced by their CHAR()-alike representation.\n'
'so input tamper script\'s name here. space/enter separator\n'
'see also: sqlmap --list-tampers',
m._tamper_area_tamper_view)
# self._set_tooltip('sqlmap itself does no obfuscation of the payload sent,\n'
# 'except for strings between single quotes replaced by their CHAR()-alike representation.\n'
# 'so input tamper script\'s name here. space/enter separator\n'
# 'see also: sqlmap --list-tampers',
# m._tamper_area_tamper_view)
self._set_tooltip('-o, checked means:\n'
' --keep-alive\n --null-connection\n --threads=3',
m._optimize_area_turn_all_ckbtn)
Expand Down
12 changes: 6 additions & 6 deletions tooltips_zh.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,12 @@ def set_all_tooltips(self, m):
self._set_tooltip('--second-req=',
m._tech_area_second_req_ckbtn,
m._tech_area_second_req_entry)
self._set_tooltip('sqlmap只会对CHAR()字符串进行混淆,\n'
'不会对其他的payload进行任何混淆.\n'
'要绕过IPS设备或Web应用防火墙(WAF)时, 使用此选项\n'
'此处填写要使用的tamper脚本名, 回车或空格拼接\n'
'详见: sqlmap --list-tampers',
m._tamper_area_tamper_view)
# self._set_tooltip('sqlmap只会对CHAR()字符串进行混淆,\n'
# '不会对其他的payload进行任何混淆.\n'
# '要绕过IPS设备或Web应用防火墙(WAF)时, 使用此选项\n'
# '此处填写要使用的tamper脚本名, 回车或空格拼接\n'
# '详见: sqlmap --list-tampers',
# m._tamper_area_tamper_view)
self._set_tooltip('-o, 开启后会默认:\n'
' --keep-alive\n --null-connection\n --threads=3',
m._optimize_area_turn_all_ckbtn)
Expand Down

0 comments on commit 8338147

Please sign in to comment.