对公司内部某个模块某个源码审计
作者:admin | 时间:2018-7-29 18:55:23 | 分类:黑客技术 隐藏侧边栏展开侧边栏
先科普一点小知识:
1.路由
经常使用或者曾经使用过ThinkPHP之类框架的人,肯定都知道路由(Route)这么一个概念,Laravel的路由配置在AppProvidersRouteServiceProvider.php中,其中function map就记录了框架的路由信息保存的位置
所以我们直接跳到路由文件去查看Laravel框架的路由是怎么写的吧
在AppHttproutes.php中
group表示在这一个group(组)里面,都使用相同的配置(应该可以这么说吧)
prefix表示无论下面是何种请求,都要在前面加上admin
namespace表示的是在哪一个命名空间内
get表示的是只允许get请求
uses后面接的东西,表示这一个请求是通过哪一个控制器的哪一个函数去进行处理的
middleware是laravel特有的中间件,就像java web的过滤器一样
下面举个例子,比如网址是www.ooxx.com:
Route::group(['namespace' => 'Admin'], function () { Route::post('new/api/login', ['uses' => 'AdminController@postLogin']); });
那么这一个路由的意思就是,处理post到http://www.ooxx.com/new/api/login的请求是由AppHttpControllersAdmin(命名空间)AdminController.php(控制器)中的postLogin函数处理。
2.中间件
中间件是Laravel特有的东西,那么这个又是在哪里定义的呢?答案就在AppHttpKernel.php中
在上文中,我们看到了有一个中间件叫token,那么放到这个图里面,我们明显发现。Token中间件就是\App\Http\Middleware\TokenSession这个类啊,那么这个类又是干嘛的呢?我们点进去看就会发现原来是验证cookie里面是否有XSRF-TOKEN和Laravel_session的
正文开始啦
通过查看路由文件,发现get请求/driver_portrait/personal_portrait_search时,在Beeper_bi_webappHttpControllersDriverPortraitDriverPortraitController.php中存在点问题。
* 点击个人画像查询数据 * * @param Request $request * @return array */ public function personalPortraitSearch(Request $request) { $this->validate($request, [ 'sub_menu_code' => 'required', ]); //前端判断ajax成功 if(empty($request->input('driver_name')) && empty($request->input('driver_id'))) { return $this->output_to_front([ 'data' => '' ]); } $where = $this->getWhere($request); //$where 是一维数组,记录了driver_name和driver_id $params['where'] = $where; $sub_menu_code = $request->input('sub_menu_code'); // personal_introduce $params['sub_menu_code'] = $sub_menu_code; $data = $this->pull('v1/report/driver_portrait/driver_portrait_search', $params, 'post', true); $data = json_decode($data, true); if ($data['code'] == 0) { $data = $this->data2Tags($data['info'][0], $sub_menu_code, $request); } return $this->output_to_front([ 'data' => $data ]); } ```
在sublime中连续ctrl+t,找到getWhere的定义处,可以明显看出来只是把提交的driver_name变量的值分割,再检查driver_id是否有值,最后返回给$where数组
public function getWhere(Request $request) { $where = []; $driver_name = $request->input('driver_name'); if (!empty($driver_name)) { if (stripos($driver_name, "|") !== false) { $arr = explode('|', $driver_name); $where[] = ['driver_name', $arr[0]]; $where[] = ['driver_id', $arr[1]]; } else { $where[] = ['driver_name', $driver_name]; } } $driver_id = $request->input('driver_id'); if (!empty($driver_id)) { $where[] = ['driver_id', $driver_id]; } return $where; }
接着又回头在personalPortraitSearch中继续运行,定义了一个$params数组,内容包含了来自客户端的sub_menu和getwhere,接着把$params数组请求远端的API
public function personalPortraitSearch() { $params = $this->request->all(); $where=$params['where']; $item=$params['sub_menu_code']; $data = $this->service->search($where,$item);// $this->setCode(1002); if(empty($data)) { return $this->Output(); } return $this->formatOutput($data); }
由此可见,直接进入search函数了,那么search函数又是在哪里定义的呢?可以看到前面是service->,那我们回到文件上方,在这个类最开始有一处定义,定义了service
跟过去看看,找到search函数,发现里面只调用了一个函数...subMenuSearch(),接着跟进去
省略部分无用代码,可以看到直接调用DB类的select方法,所以产生注入。
附上SQLMap的运行截图吧