国铁路物资集团有限公司(简称中国铁物)是国务院国资委监管的大型中央企业,是我国规模最大、服务能力最强、专业经验最丰富、行业领先的铁路生产性服务综合提供商。集团公司总部设在北京,在全国及美国、澳大利亚、老挝等国家拥有100多家分支机构。经营业务主要围绕国内外铁路运营、装备制造、建设施工,涉及铁路油品、轨道、装备、铁建、工业、物流、国际及相关多元等领域。
根据公司发展需要,中国铁物现就以下岗位面向社会进行公开招聘。
招聘岗位及资格条件
(一)招聘部门:集团总部法律合规部
招聘岗位:法律顾问(经理)1人
岗位职责:
1.参与公司重大项目的法律事务,提供法律咨询与服务;
2.负责集团公司总部工商登记管理和证照管理,办理分子公司工商批复并监督检查证照使用管理工作;
3.参与公司诉讼案件管理;
4.审查合同,对公司业务发展中的法律风险进行分析,并提供法律意见和建议;
5.部门综合事务和其他法律事务。
岗位任职资格:
1.全日制大学本科及以上学历,法学相关专业;
2.5年以上工作经历,3年及以上企业法律顾问或律师事务所、法院、检察院工作经历;
3.具有法律执业资格或企业法律顾问资格;
4.具备较强的语言表达能力、逻辑能力、分析能力及良好的团队协作精神;
5.人品正直,作风正派,具有良好的职业素养和抗压能力,无违规违纪违法等不良记录;
6.具有良好的心理素质,身体健康,年龄一般不超过35周岁。
(二)招聘部门:集团公司所属信息中心
招聘岗位:系统管理经理 1人
岗位职责:
1.负责集团数据中心的构架优化、建设和实施工作;
2.负责集团数据中心服务器、数据库、备份容灾系统等基础设施平台系统的监控和维护工作;
3.负责集团各部门及分、子公司基础设施方面运行情况的监督和咨询支持工作;
4.配合完成数据中心相关网信安全工作;
5.协助完成集团总部办公网络维护工作;
6.承办上级交办的其他工作。
岗位任职资格:
1.计算机类、软件类相关专业本科及以上学历;
2.对集团级数据中心有深入理解,具备信息化基础设施平台5年以上实施和运维经验;
3.熟悉数据库系统理论知识。熟悉ORACLE数据库系统,理解ORACLE数据库体系结构。能规划并熟练安装配置和维护多实例ORACLE数据库系统,熟悉RAC、DG等,熟悉ORACLE备份恢复机制,熟练使用PL/SQL等相关开发运维工具;了解SQL-server、MYSQL数据库;具有相关产品认证;
4.熟悉PC服务器和小型机服务器产品,熟悉AIX系统的安装、配置和维护;熟练运用LINUX系统;熟练运用windows server系统;具有shell、python(至少一种)编程能力;熟练搭建、维护ftp、nginx、apache、zabbix等服务及应用能力;
5.熟悉云计算技术和私有云搭建方式,有维护云主机与云数据库经验;熟悉1-2种虚拟化管理软件,具备VMware虚拟化环境的规划、实施和运维能力;
6.了解SAP系统体系结构,了解SAP系统维护的主要内容,有SAP basis经验为佳;
7.了解企业数据网络管理,了解TCP/IP协议及网络基础知识。熟悉H3C、Juniper、Cisco、radware、深信服等主流网络产品的配置和使用。了解网络安全知识。了解ITIL运维体系;
8.身体健康,年龄一般不超过40周岁。
招聘岗位:系统开发运维经理 1人
岗位职责:
1.负责制定系统开发和集成技术规范;
2.负责自开发系统需求分析、系统设计、代码编写与系统运行管理;
3.负责自开发系统代码库管理,保证代码库及时更新;
4.负责开发文档、开发外包的管理工作;
5.负责自开发及相关系统的安装、升级、日常运行监控和培训工作;
6.承办上级交办的其他工作。
岗位任职资格:
1.计算机类、软件类相关专业本科及以上学历;
2.6年以上软件开发经验,3年以上大型企业级系统架构设计开发经验,具备独立设计开发系统能力;
3.熟练使用两种以上常用开发框架:Spring、JFinal、Hibernate、Mybatis等;
4.熟练使用 JavaScript、Jquery、Html、CSS、AJAX及前端UI工具;
5.熟练使用JAVA开发语言,了解C#、ABAP开发语言及企业开发方法;
6.熟悉GIT、SVN等开发管理工具;
7.熟悉主流数据库Oracle、SQLServer、MySQL等,精通Oracle数据库,能熟练使用存储过程、视图等;
8.熟悉项目管理理论,熟悉敏捷和CMMI开发模式;
9.最好具备仓储物流相关业务知识;
10.具有良好的沟通能力及团队协作精神,责任心强;
11.身体健康,年龄一般不超过40周岁。
(三)招聘单位:中企云商物流(北京)有限公司
招聘岗位:法律顾问1人
岗位职责:
1.负责对公司经营和决策提出法律意见;
2.负责合同评审工作,参加合同的谈判和起草;
3.建立公司合规管理体系,开展合规管理工作,对业务过程进行监控,防范经营风险;
4.组织、参与公司规章制度体系建设;
5.处理公司法律纠纷,代理公司仲裁、诉讼、行政复议等工作。
岗位任职资格:
1.全日制大学本科及以上学历,法学、法律相关专业;
2. 2年及以上工作经历,具有企业法务管理、律师、法院、检察院等工作经历者优先;
3.具备良好的法律基础和企业法律知识,熟悉国内贸易、物流、供应链行业法律规定者优先;
4.具有较强组织协调能力、执行能力和抗压能力;
5.具有良好的职业道德,较强的责任心和团队协作精神,无违规违纪违法等不良记录;
6.具有良好的心理素质,身体健康,年龄一般不超过35周岁。
招聘程序
1.招聘人员录用工作按照自愿报名、资格审查、笔试、面试、组织考察、决定聘用的程序进行。
2.按照有关规定,对招聘正式聘用人员实行任职试用期。
报名方式、要求及截至时间
报名方式:下载并填写《公开招聘报名表》(见附件)。
应聘邮件标题格式:“应聘岗位+姓名+现单位及职务”。应聘人员需将本人学历学位证书、身份证、职称证书、两寸彩色照片、相关工作业绩证明等材料,扫描件打包一并发送至报名电子邮箱binfei_1981@163.com。
中国铁物总部及所属信息中心岗位联系方式:
电话:010-51899255 报名邮箱:hr@crmsc.com.cn
中企云商物流(北京)有限公司岗位联系方式:
电话:010-57649387 报名邮箱:binfei_1981@163.com
报名截至时间:2019年7月17日
来源:国务院国有资产监督管理委员会
责任编辑:王迪
“人民旅游”
分享你的游记与攻略,展示你的美景与美食,代你体验不一样的风景与风情。
AiJ是一套完整的房间类游戏解决方案,支持无限水平扩展来满足更大的人数承载,并且提供了良好的调试接口。
主要模块包括:
SQL注入漏洞可以说是在企业运营中会遇到的最具破坏性的漏洞之一,它也是目前被利用得最多的漏洞。要学会如何防御SQL注入,首先我们要学习它的原理。
针对SQL注入的攻击行为可描述为通过在用户可控参数中注入SQL语法,破坏原有SQL结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为以下两个原因叠加造成的:
程序编写者在处理应用程序和数据库交互时,使用字符串拼接的方式构造SQL语句。未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中。
注入攻击的本质,是把用户输入的数据当做代码执行。这里有两个关键条件:用户能够控制输入。
原本程序要执行的代码,拼接了用户输入的数据。
手动找的话,可以直接找到sqlmapper.xml文件或者直接搜索 select、update、delete、insert “String sql=”等关键词,定位SQL xml配置文件。
如果 sql 语句中有出现 $ 进行参数拼接,则存在SQL注入风险。
当找到某个变量关键词有 SQL 注入风险时,可以再根据调用链找到该存在注入风险的业务逻辑代码,查看参数来源是否安全、是否有配置SQL危险参数过滤的过滤器,最终确认是否存在SQL注入。以下给出可能造成sql注入攻击的关键字,审计时可根据实际情况进项查找
常见SQL语句关键词
关键词 | 解释 |
ResultSet | 数据库结果集的数据表,通常通过执行查询数据库的语句生成。 |
executeQuery | 执行查询 |
select | 数据库中的查询关键字 |
insert | 数据库中的插入关键字 |
update | 数据库中的修改关键字 |
delete | 数据库中的删除关键字 |
where | 数据库中的条件关键字 |
union | 数据库中的联合查询关键字 |
drop | 数据库中的删除数据库关键字 |
create | 数据库中的创建数据库关键字 |
count | 数据库中的返回匹配行数关键字 |
java.sql.Connection | 与特定数据库的连接类 |
Statement | 是 Java 执行数据库操作的重要接口 |
jdbcTemplate | 最基本的Spring JDBC模板 |
PreparedStatement | 预编译的 SQL 语句的对象 |
queryForInt | 数据库查询方法关键字 |
queryForObject | 数据库查询方法关键字 |
queryForMap | 数据库查询方法关键字 |
getConnection | 获取sql连接 |
outfile | 数据库中把表数据导出关键字 |
load_file | 数据库中导入数据的关键字 |
【一一帮助安全学习,以下都是免费获取,文末有领取方式~一一】
①网络安全学习路线
②20份渗透测试电子书
③安全攻防357页笔记
④50份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100个漏洞实战案例
⑧安全大厂内部教程
1 、 攻击者可以做到
2、可能对业务造成的影响
① 用户信息被篡改
② 攻击者偷取代码和用户数据恶意获取
线上代码被非法篡改,并造成为恶意攻击者输送流量或其他利益的影响
Statement stmt = null;
ResultSet rs = null;
try{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String sqlString = "SELECT * FROM t_item WHERE owner='" + userName + "' AND itemName='" + request.getParameter("itemName") + "'";
stmt = connection.createStatement();
rs = stmt.executeQuery(sqlString);
// ... result set handling
}
catch (SQLException se){
// ... logging and error handling
}
这里将查询字符串常量与用户输入进行拼接来动态构建SQL查询命令。仅当itemName不包含单引号时,这条查询语句的行为才会是正确的。如果一个攻击者以用户名wiley发起一个请求,并使用以下条目名称参数进行查询:
name' OR 'a' = 'a
那么这个查询将变成:
SELECT * FROM t_item WHERE owner = 'wiley' AND itemname = 'name' OR 'a'='a';
此处,额外的OR ‘a’='a’条件导致整个WHERE子句的值总为真。那么,这个查询便等价于如下非常简单的查询:
SELECT * FROM t_item
这个简化的查询使得攻击者能够绕过原有的条件限制:这个查询会返回items表中所有储存的条目,而不管它们的所有者是谁,而原本应该只返回属于当前已认证用户的条目。
在存储过程中动态构建SQL
Java代码:
CallableStatement = null
ResultSet results = null;
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
cs = connection.prepareCall("{call sp_queryItem(?,?)}");
cs.setString(1, userName);
cs.setString(2, itemName);
results = cs.executeQuery();
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
SQL Server存储过程:
CREATE PROCEDURE sp_queryItem
@userName varchar(50),
@itemName varchar(50)
AS
BEGIN
DECLARE @sql nvarchar(500);
SET @sql = 'SELECT * FROM t_item
WHERE owner = ''' + @userName + '''
AND itemName = ''' + @itemName + '''';
EXEC(@sql);
END
GO
在存储过程中,通过拼接参数值来构建查询字符串,和在应用程序代码中拼接参数一样,同样是有SQL注入风险的。
原生SQL查询:
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query sqlQuery = session.createSQLQuery("select * from t_item where owner = '" + userName + "' and itemName = '" + itemName + "'");
List<Item> rs = (List<Item>) sqlQuery.list();
HQL查询:
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query hqlQuery = session.createQuery("from Item as item where item.owner = '" + userName + "' and item.itemName = '" + itemName + "'");
List<Item> hrs = (List<Item>) hqlQuery.list();
即使是使用Hibernate,如果在动态构建SQL/HQL查询时包含了不可信输入,同样也会面临SQL/HQL注入的问题。
HQL代码中,session.createQuery使用HQL语句将查询到的数据存到到list集合中,需要时在拿出来使用。而参数中itemName是通过request.getParameter直接获取。攻击者若在此处写入恶意语句,程序将恶意语句查询出来的数据存放在list集合中,再通过某处调用成功将数据显示在前台。
Mybatis框架下易产生SQL注入漏洞的情况主要分为以下三种:
1)模糊查询like
例如对人员姓名检索进行模糊查询,如果考虑安全编码规范问题,其对应的SQL语句如下:
Select * from user where name like '%#{name}%'
但由于这样写程序会报错,研发人员将SQL查询语句修改如下:
Select * from user where name like '%${name}%'
在这种情况下我们发现程序不再报错,但是此时产生了SQL语句拼接问题,如果java代码层面没有对用户输入的内容做处理势必会产生SQL注入漏洞。
2)in之后的参数
例如对人员姓名进行同条件多值检索的时候,如当用户输入001,002,003…时,如果考虑安全编码规范问题,其对应的SQL语句如下:
Select * from name where id in (#{id})
但由于这样写程序会报错,研发人员将SQL查询语句修改如下:
Select * from name where id in (${id})
修改SQL语句之后,程序停止报错,但是却引入了SQL语句拼接的问题,如果没有对用户输入的内容做过滤,势必会产生SQL注入漏洞。
3)order by之后(重点和区分点)
当根据姓名、id序号等信息用户进行排序的时候,如果考虑安全编码规范问题,其对应的SQL语句如下:
Select * from user where name = 'qihoo' order by #{id} desc
但由于发布时间id不是用户输入的参数,无法使用预编译。研发人员将SQL查询语句修改如下:
Select * from user where name = 'qihoo' order by ${id} desc
修改之后,程序未通过预编译,但是产生了SQL语句拼接问题,极有可能引发SQL注入漏洞。
本文中使用ofcms进行SQL注入漏洞讲解,此CMS算是对新手学习代码审计比较友好的CMS。
上述为安装成功页面,如何安装CMS本章不在赘述。
后台页面:http://localhost:8080/ofcms-admin/admin/index.html
漏洞点:
ofcms-admin/src/main/java/com/ofsoft/cms/admin/controller/system/SystemGeneratrController.java
create方法
|
/**
* 创建表
*/
public void create() {
try {
String sql = getPara("sql");
Db.update(sql);
rendSuccessJson();
} catch (Exception e) {
e.printStackTrace();
rendFailedJson(ErrorCode.get("9999"), e.getMessage());
}
}
上述代码中使用getpara获取sql的参数值,并update,跟进一下getpara和update方法。
跳转至 jfinal-3.2.jar/com/jfinal/core/controller.class
public String getPara(String name) {
return this.request.getParameter(name);
}
上述代码无特殊用意,就是获取参数值,继续跟进 Db.update 方法。
跳转至 jfinal-3.2.jar/com/jfinal/plugin/activerecord/Db.class
public static int update(String sql) {
return MAIN.update(sql);
}
发现调用 MAIN.update , 继续跟进。
跳转至 jfinal-3.2.jar/com/jfinal/plugin/activerecord/DbPro.class
public int update(String sql) {
return this.update(sql, DbKit.NULL_PARA_ARRAY);
}
继续跟进到最后,发现华点。
public int update(String sql, Object... paras) {
Connection conn = null;
int var4;
try {
conn = this.config.getConnection();//连接
var4 = this.update(this.config, conn, sql, paras);//调用update更新
} catch (Exception var8) {
throw new ActiveRecordException(var8);
} finally {
this.config.close(conn);
}
return var4;
}
重点:Object…
Object是所有类的基类,而 Object… 是不确定方法参数情况下的一种多态表现形式(可以传递多个参数)。
再继续跟进 update ,同文件代码
int update(Config config, Connection conn, String sql, Object... paras) throws SQLException {
PreparedStatement pst = conn.prepareStatement(sql);
config.dialect.fillStatement(pst, paras);
int result = pst.executeUpdate();
DbKit.close(pst);
return result;
}
上述代码执行SQL语句,并返回结果。
至此,整个功能流程结束,在我们跟进的过程中,代码中无任何过滤语句,获取参数值,调用update方法更新,更新成功后返回结果。
漏洞点打上断点,网页中输入poc进行验证
update of_cms_topic set topic_url=updatexml(1,concat(0x7e,(user())),0) where topic_id = 1
根据如上截图可看出我们传入的SQL语句是被完整的接收,并未做任何过滤直接带入数据库执行,所以此处直接写入漏洞代码爆出当前数据库账户为 root。
上述为sqlmap工具跑出来的注入点。
SQLFilter.java中:
如果使用参数化查询,则在SQL语句中使用占位符表示需在运行时确定的参数值。参数化查询使得SQL查询的语义逻辑被预先定义,而实际的查询参数值则等到程序运行时再确定。参数化查询使得数据库能够区分SQL语句中语义逻辑和数据参数,以确保用户输入无法改变预期的SQL查询语义逻辑。
在Java中,可以使用java.sql.PreparedStatement来对数据库发起参数化查询。在这个正确示例中,如果一个攻击者将itemName输入为name’ OR ‘a’ = ‘a,这个参数化查询将免受攻击,而是会查找一个itemName匹配name’ OR ‘a’ = 'a这个字符串的条目。
PreparedStatement stmt = null
ResultSet rs = null
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
// ...Ensure that the length of userName and itemName is legitimate
// ...
String sqlString = "SELECT * FROM t_item WHERE owner=? AND itemName=?";
stmt = connection.prepareStatement(sqlString);
stmt.setString(1, userName);
stmt.setString(2, itemName);
rs = stmt.executeQuery();
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
这个存储过程使用参数化查询,而未包含不安全的动态SQL构建。数据库编译此存储过程时,会生成一个SELECT查询的执行计划,只允许原始的SQL语义被执行。任何参数值,即使是被注入的SQL语句也不会被执行,因为它们不是执行计划的一部分。
CallableStatement = null
ResultSet results = null;
try
{
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
// ... Ensure that the length of userName and itemName is legitimate
// ...
cs = connection.prepareCall("{call sp_queryItem(?,?)}");
cs.setString(1, userName);
cs.setString(2, itemName);
results = cs.executeQuery();
// ... result set handling
}
catch (SQLException se)
{
// ... logging and error handling
}
Hibernate支持SQL/HQL参数化查询。为了防止SQL注入以及改善性能,以上这些示例使用了参数化绑定 的方式来设置查询参数。
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query hqlQuery = session.createQuery("from Item as item where item.owner = ? and item.itemName = ?");
hqlQuery.setString(1, userName);
hqlQuery.setString(2, itemName);
List<Item> rs = (List<Item>) hqlQuery.list();
HQL基于名称的参数化查询
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query hqlQuery = session.createQuery("from Item as item where item.owner = :owner and item.itemName = :itemName");
hqlQuery.setString("owner", userName);
hqlQuery.setString("itemName", itemName);
List<Item> rs = (List<Item>) hqlQuery.list();
原生参数化查询
String userName = ctx.getAuthenticatedUserName(); //this is a constant
String itemName = request.getParameter("itemName");
Query sqlQuery = session.createSQLQuery("select * from t_item where owner = ? and itemName = ?");
sqlQuery.setString(0, owner);
sqlQuery.setString(1, itemName);
List<Item> rs = (List<Item>) sqlQuery.list();
尽量使用#描述参数,如果一定要使用$,则需要自己过滤用户输入
模糊查询like SQL注入修复建议
按照新闻标题对新闻进行模糊查询,可将SQL查询语句设计如下:
select * from news where name like concat(‘%’,#{name }, ‘%’)
采用预编译机制,避免了SQL语句拼接的问题,从根源上防止了SQL注入漏洞的产生。
in之后的参数SQL注入修复建议
在对新闻进行同条件多值查询的时候,可使用Mybatis自带循环指令解决SQL语句动态拼接的问题:
select * from news where id in<foreach collection="ids" item="item" open="("separator="," close=")">#{item} </foreach>
order by SQL注入修复建议
在Java层面做映射预编译机制只能处理查询参数,其他地方还需要研发人员根据具体情况来解决。如前面提到的排序情景:
Select * from news where title =‘淘宝’ order by #{time} asc,
这里time不是查询参数,无法使用预编译机制,只能这样拼接:
Select * from news where title =‘淘宝’ order by ${time} asc
针对这种情况研发人员可以在java层面做映射来进行解决。如当存在发布时间time和点击量click两种排序选择时,我们可以限制用户只能输入1和2。
当用户输入1时,我们在代码层面将其映射为time,当用户输入2时,将其映射为click。而当用户输入1和2之外的其他内容时,我们可以将其转换为默认排序选择time(或者click)。
*请认真填写需求信息,我们会在24小时内与您取得联系。