Code Security Guide-Thinkphp3.2.3框架安全分析+exp注入(一)

  • Comments Off on Code Security Guide-Thinkphp3.2.3框架安全分析+exp注入(一)
  • 16 views
  • A+

0x01 Thinkphp 3.2.3 安装配置

1.1 环境

版本:Thinkphp full.zip

php环境版本5.6以上

服务器环境:phpstudy

使用工具:xdebug 、phpstorme

1.2 打开 TP 调试开关

设置定义应用目录,可以调整成我们自己设置的数据库。接着打开调试模式, 定义我们要用的应用目录,在前面得文章中讲过。这里不多赘述。

wKg0C2E346AJInHAAC4BXmiYSQ514.png

设置数据库 在ThinkPHP->Conf->convention.php文件夹下 复制我们的数据库设置代码,代码复制到Home->Conf->config.php下

wKg0C2E36SAbX5UAADL0I2zbO8966.png

配置控制器 修改IndexController.class.php内的代码。这个数据库是之前搞过二次开发的数据库。

wKg0C2E37GAbGZpAACI8sSFeu4614.png

wKg0C2E37mASNpBAACBxLRp5SY753.png

1.3 打开日志设置

开启调试追踪 'SHOW_PAGE_TRACE'=>true,在config.php下(之前修改数据库操作的.php文件)

wKg0C2E4BaAdV9sAADT4PPx3EM842.png

就会出现下面这种情况:可以看到数据的回显。

wKg0C2E4CiAef5wAACYVSVawUQ938.png

0x02 ThinkPHP 数据库操作分析

数据库操作路线:

1、M() 函数会自动创建一个new model类 并且实例化一个对象返回此资源

2、如果实例化comment 对象调用了where方法同时格式化处理然后会调用-->$options

3、对$options做一次分析:

4、接下来会调用find()方法,find()方法会先给‘user’对象的一个成员变量$options赋值,limit=1。然后进入select()

5、select()方法会直接buildselectsql()

直接看源码进行分析

准备的控制器:

wKg0C2EFAKAEgOuAAEmpJCZP0211.png

按照我们上面的路线一步一步调试过来,分析一下数据库的操作

M()函数 实例化一个comment对象

M()->where()->find()

wKg0C2EQsSATkJwAACKlSKnGM8555.png

where()函数

where方法使用字符条件,并且支持预编译。

wKg0C2EQtqAV0g6AACyAWdh7hA653.png

wKg0C2EQueAPpKzAADzqrxh4d0226.png

也就是说:普通的注入("id=%d and username='%s' and xx='%f'")然后会直接ThinkPHP都会进行escape_string处理

注意: mysql_escape_string() 并不转义 % 和 _。 本函数和 mysql_real_escape_string() 完全一样,除了 mysql_real_escape_string() 接受的是一个连接句柄并根据当前字符集转移字符串之外。mysql_escape_string() 并不接受连接参数,也不管当前字符集设定。

mysql_escape_string() 的作用和addslashes的作用差不多

分析find()函数

find()-->parseOptions()-->select()最后才创建buildselectsql() 函数。

wKg0C2EQ1mAfxaBAAC4tFiTNjc298.png

1、 接着进入到options()中 主要作用就是获取操作的表名,查看是否有取别名获取操作的模型,比对当前表的数据库字段是否一致,如果有不一致的字段$this->options

wKg0C2EQ2mAJImoAAC2g93JINE884.png

parseType() 功能是对数据类型进行检测 并强制转换.

wKg0C2EQ3iAAe3UAAB9YLBP9k914.png

select()

执行 $this->db->select( options)

wKg0C2EQ6mAaLDjAABcLjCI2u0925.png

buildSelectSql()

db-select()->buildSelectSql() 分页操作,最后直接执行pareSql(). parseSql函数 函数调用了str_replace()对sql语句做了一次安全检查

wKg0C2EQ8CAJhKBAABjQ8T7slY286.png

pareSql() ->parseTable()

wKg0C2EQ9eANwynAAB09g9X5o673.png

wKg0C2EQ96AU9vTAABVnKcOu30094.png

parseWhere()方法分析,,这里进行拼接字符串,parseKey()过滤,然后返回

wKg0C2EQ2AaYUZAAC8Tues3R8482.png

wKg0C2EQaAOahVAACtCcFHCpM832.png

parWhereItem()函数 ,这里是个重点接下来两个漏洞利用都与这有关系

wKg0C2ERBWAJh0rAADPlgArIos896.png

parseValue() -->用来判断传进来的是数组还是字符串。然后根据不同调用escapeString()

方法。

wKg0C2ERCSAT1N3AABT6vgbPDo840.png

最后生成sql语句

wKg0C2ERDaALGlAABX217hKoc800.png

0x03 总结分析

分析完之后能看到 在parWhereItem()函数里 明显就有两个漏洞生成。后面的文章会先对这两个漏洞进行分析。

wKg0C2ERuKAcRfgAADPlgArIos307.png

0x0a、漏洞利用 (GET传参,exp注入)

前面那篇文章,我们在parseWhereItem()函数 里看到两个漏洞,接下来就直接进行分析了。

利用的exp

```

id[0]=exp&id[1]=='1' and updatexml(1,concat(0x3a,user(),0x3a),1)--+

```

wKg0C2EVX2AH3PAADIjToF7YY583.png

控制器代码

wKg0C2EWsyAQIPOAAAmlxhMco439.png

关于M函数和where函数都分析过了,现在也不在这里过多的赘述。where()->select()->db-select()->buildSelectSql()

分析where()函数--对parseWhereItem函数进行分析

wKg0C2EVZKARUPUAACpUqDXGQo500.png

最关键的是:

```

elseif('exp' == $exp ){ // 使用表达式

                $whereStr .= $key.' '.$val[1];

```

直接拼接了sql语句 。直接导致sql注入成功

wKg0C2EWgaAfqeRAACiHzXuBbI655.png

生成的sql语句 拿到数据库去执行一下

wKg0C2EWimALiRtAABYlip2ZBU612.png

0x0c、漏洞修复

因为前面的id值是通过GET传值,没有做任何的过滤。现在使用I()接受id传值 ,然后 接收到传值之后I函数会做一次过滤

wKg0C2EW0qAArbxAABL9j5Lhk933.png

看一下拼接的sql语句

wKg0C2EW2uAUyO8AABzJVcU58755.png

wKg0C2EW3iAexwoAAB8NMuHFNw495.png

直接防住了 exp传值。

分析一下:I()函数会直接运行到think_filter()函数

wKg0C2EXKKAAPU4AABMXb78Yfg877.png


关于数据库的第二个漏洞,属于同一种类型,不多bb直接写了

相关推荐: vulnhub-hackeme2

靶机描述 'hackme2' is a medium difficulty level box. This is the second part of the hackme series where more controls are in place do …