XL某服务器svn源码泄露 可SQL 影响海量用户数据

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】
此文,在2016-04-23 12:28已经通过WOOYUN系统报告给XL,并且早已修复。所以这里公开。
其实挺简单的,无意中找到了一处 http://xxx.xxx.xxx.xxx:8080/.svn/entries
然后果断把源码下载下来。第一步直接看数据库文件配置:
数据库没有外联。咱们访问一下网站,地址:http://xxx.xxx.xxx.xxx:8080/exxxrt/Drixxxxpply 访问提示无权限。如图:
所以,咱们只能通过源码入手。下面咱们通过下载下来的源码审计一下。因为没有找到登录口,直接提示无权限,所以只能是查看一下源码,是如何限制的。如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | private $_domain = 'http://211.81.13.211:8080/'; public function index() { $data['domain'] = $this->_domain; $data['left']=array( array( 'name'=>'自驾游列表', 'page'=>'exxxrt/Drixxxply/datalist' ) ); $this->load->view('exxxrt/index',$data); } private function _check(){ $cross_ip_arr = array('211.81.5.211','127.0.0.1'); $ip = ip(); if(!in_array($ip,$cross_ip_arr)){ echo '无权限'; exit; } return true; } |
从这里我好象懂了什么,,,。莫非,,,只允许IP 为'211.81.5.211','127.0.0.1' 这两的地址访问? 咱们直接X-Forwarded-For 然后访问试试。。。
看到了吧,成功进入网站!!!但是后台功能实在太简洁明了了。。。试着审计一下源码,看看能否深入利用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | public function datalist($curpage = 1) { $this->_check(); $size = 50; $offset = intval($curpage) <= 0 ? 0 : (intval($curpage) - 1) * $size; $sql = "SELECT * FROM bizcar_drive_apply where 1=1"; $sql .= $this->_param(); //echo 注意,下面没过滤的参数全部都传到了这里!!! $count = count($this->db->query($sql)->result_array()); $sql .= " order by id desc"; $sql = $sql . " limit " . $offset . "," . $size; $data['list'] = $this->db->query($sql)->result_array(); $urls = array(); foreach ($data['list'] as $k => $v) { $data['list'][$k]['car_name'] = $this->_getSubName($v['brand_id'], $v['sub_brand_id'], $v['car_id']); $area = $this->_getProvinceCity($v['province_id'], $v['city_id']); if (empty($urls[$v['article_id']])) { $tmp = $this->_getUrl($v['article_id']); if (!empty($tmp)) { $urls[$v['article_id']] = $tmp; } } $data['list'][$k]['url'] = empty($urls[$v['article_id']]['url']) ? '' : $urls[$v['article_id']]['url']; $data['list'][$k]['area'] = implode('-', $area); } $json = $this->config->item('city_json'); $data['area_json'] = $json; $data['area'] = json_decode($json, true); $config['num_tag_open'] = $config['prev_tag_open'] = $config['next_tag_open'] = $config['last_tag_open'] = $config['first_tag_open'] = '<li>'; $config['num_tag_close'] = $config['prev_tag_close'] = $config['next_tag_close'] = $config['last_tag_end'] = $config['first_tag_close'] = '</li>'; $config['cur_tag_open'] = '<li class="active"><a>'; $config['cur_tag_close'] = "</li></a>"; $config['reuse_query_string'] = true; $data['pages'] = create_page($this->_domain.'exxxrt/Drixxxxply/datalist', $count, $curpage, $size, 4, $config); $data['province_id'] = intval($this->input->get('province_id')); $data['city_id'] = intval($this->input->get('city_id')); $data['domain'] = $this->_domain; $data['left']=array( array( 'name'=>'自驾游列表', 'page'=>'exxxrt/Drivxxxxply/datalist' ) ); $this->load->view('exxxrt/temp_drive_apply_view', $data); } private function _param() { $article_title = $this->input->get('article_title'); $user = $this->input->get('user'); $user_mobile = $this->input->get('user_mobile'); $start_time = $this->input->get('start_time'); $end_time = $this->input->get('end_time'); $province_id = intval($this->input->get('province_id')); $city_id = intval($this->input->get('city_id')); $ret = ''; if (!empty($article_title)) { $ret .= " and article_title like '%" . trim($article_title) . "%'"; } if (!empty($user)) { $ret .= " and user like '%" . trim($user) . "%'"; } if (!empty($user_mobile)) { $ret .= " and user_mobile = '" . trim($user_mobile) . "'"; } if (!empty($start_time)) { $ret .= " and date >= '" . $start_time . "'"; } if (!empty($end_time)) { $ret .= " and date <= '" . $end_time . "'"; } if ($province_id > 0) { $ret .= ' and province_id = ' . $province_id; if ($city_id > 0) { $ret .= ' and city_id = ' . $city_id; } } return $ret; // 注意这里,这里把上面没过滤的参数的值组成SQL语句,返回 } |
基本完全没过滤啊。。。
$article_title = $this->input->get('article_title'); //此处完全没过滤
$user = $this->input->get('user'); //此处完全没过滤
$user_mobile = $this->input->get('user_mobile'); //此处完全没过滤
$start_time = $this->input->get('start_time'); //此处完全没过滤
$end_time = $this->input->get('end_time'); //此处完全没过滤
$province_id = intval($this->input->get('province_id')); //此处只能为数字
$city_id = intval($this->input->get('city_id')); //此处只能为数字
看上面,我已经说明了,那这么简单,就不麻烦了。。。。。。 下面愿意练习手工的就手工,不愿意的直接用工具。但是我表示。。。还是工具快点。。。
直接SQLMAP
然后发现有一个错误可以直接泄露路径!!如图:
但是可惜注入点权限限制的太严格,并没办法利用。 最后也只能这样作罢。。。好了,简单看一下数据量。
这里注意,千万不要脱裤做傻事哦。
back-end DBMS: MySQL 5.0
Database: weidealer
+-------------------+---------+
| Table | Entries |
+-------------------+---------+
| bizcar_user_trace | 3672849 |
| weixin_userinfo | 90723 |
| bizcar_admin_info | 46 |
+-------------------+---------+
你咋搜索到crm的。。