前言:假期就这么来了,7月份,在家也要保持学习呀!!!
Web
Login as admin
题目改编自 Zer0pts CTF 2020
,此题是无敌简化版,考点是 SSTi
和 flask的session伪造
首先源码已经给出来了,分析一波源码:
1 | import flask |
构造 Referer:http://47.110.130.169:12222/
,然后需要触发404,地址栏随便输入一个不存在的页面:
访问后可以发现触发到了
然后可以发现地址栏多了一堆配置,拿去url解码一下,就可以看到完整的配置了。
1 | <Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'wustaismatr1x2333333333333333333333333333', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(days=31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': False, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(seconds=43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093}> |
可以得到 'SECRET_KEY': 'wustaismatr1x2333333333333333333333333333'
于是我们可以利用key来伪造session:{"user":"admin"}
可以自己开一个flask项目,可以直接用工具:Github项目链接
得到session后放在cookie里,访问 /admin
真·签到题
大人,时代变了
0x0 前言
出这个题的本意是看到CTF的web题老是PHP什么的, 感觉和现实情况有点脱节, 且对前端审计没有太大的要求, 于是出了这个”现代”一点的题. 这个题目模拟的是爬虫, 在多次请求后将会出现验证码, 再频繁访问将会封锁ip, 且网站是使用React写的, 经过webpack的打包和混淆使得js很难读, 不过这也是大势所趋, 出出来涨涨见识吧.
0x1 前端审计
首先打开网站, hint提示用户识别码只有3位
抓包
F12进行抓包, 发现有uuid
和img
两个字段, img毫无疑问是验证码了, uuid确是一个base64, 尝试解码, 无法得到数据
尝试构造随意数据发送, 再在F12里查看, 发现请求中uuid为f56d359611c24abf9aa1d9f0113091a4
, 说明前端对此数据进行了解密, 首先对前端代码进行审计, 查找加密算法
逻辑分析
打开前端代码后, 我相信不少人肯定是蒙的, 首先先进行格式化, 其大概画风是这样的
让我们一步一步来, 首先看点击登录后发生了什么, 搜索关键词登录
, 可以找到这里
可以看见登录按钮绑定了一个函数this.w
, 进入this.w看干什么了
分析: 这里的switch其实是一个
async
函数, 通过babel
进行转义的结果, 建议学习ES6, 7, 8, 勉强可以进行分析
- 进入case0, 将
state.l = true
, 然后调用a.__.q(state.w, state.c, state.p)
- 进入case4,
alert(t.msg)
可以发现这里就是弹出服务器错误提示的地方 - 进入case9,
t0 = _.catch(0), alert(t0)
, 这里是处理错误的地方 - 进入case12, 调用
a.u()
, 然后state.l = false
进入a.__.q(e, t, a)
, 应该有三个参数, 分析逻辑
一眼看到熟悉的200, 说明这里应该就是发送数据的地方, 查看参数
在这里我们发现大量w({Base64})
的东西, 通过定位发现w为Base64解码, 吧base64拿去解码, 发现为发送数据的隐藏, 比如uuid
, code
. 这种方式很常见, 为了防止直接搜索直接对数据进行base64储存
查看参数, 这么一长串为
Object(F_Web_Project_fucking_test_node_modules_babel_preset_react_app_node_modules_babel_runtime_helpers_esm_defineProperty__WEBPACK_IMPORTED_MODULE_6__.a)(l, w("bWV0aG9k"), w("UE9TVA=="))
前面那么一长串其实是命名空间, 经过化简后可以得到{method: "POST"}
, 发现为fetch的用法, 但是在这里并没有发现加密, 说明加密不在发送数据的时候
再次观察请求, 发现在进行一次POST后, 立马获取了一个新的uuid, 说明在登录后应该调用了获取新的uuid的函数, 经过上面分析async
, 进入a.u()
解密算法
又是一个类似的函数, 这里我们可以直接聚焦到可疑函数a.setState({g: e.img, p: a.__.p(e[t("dXVpZA==")])})
, 可以看到验证码被保存了, 而dXVpZA==
就是uuid, 说明uuid经过了a.__p() e[] t()
的处理, 一个个跟踪
- 首先发现t为Base64解码函数, 现在为
a.__.p(e['uuid'])
- 可以知道e为返回数据, 那么解码就在
a.__.p()
里 - 进入p, 首先对uuid进行
Base64.toUnit8Array
, 然后与___
进行遍历 - 寻找
___
, 发现为___ = new Uint8Array([49, 50, 51, 67, 55, 69, 53, 69, 56, 55, 53, 70, 66, 70, 48, 69, 69, 69, 50, 53, 56, 51, 70, 56, 65, 70, 51, 68, 68, 70, 70, 57])
可以拼出内容 - 追踪
__
, 发现为xor - 那么整个算法就清晰了, 使用python进行模拟
1 | def parse_uuid(raw): |
0x2 验证码识别
验证码识别有多种办法, 包括接入打码平台, 使用ocr开源项目, 这里验证码十分规整, 我可以手写一个验证码识别
分析
首先分析验证码结构, 数字8721
分别距离左边5, 20, 35, 50
, 字母大小为12*18
多次刷新, 采集多个验证码, 我这里采集了5个集齐了所有数字
验证码处理
首先将验证码分隔成4个独立的小数字, 使用Python的PIL模块
1 | for i in range(4): |
然后对整个图片灰度化处理data = data.convert("L")
然后简单对图片黑白化, 由于背景是白色的, 这里认为凡是不是白色即为有数据
1 | w, h = data.size |
最后保存图片, 总体代码
1 | import uuid |
特征提取
将图片进行重命名, 挑出1-9
, 并且重命名, 对数据进行采集
1 | from PIL import Image |
最终获取json数据一份
至于识别, 只需要对图片进行相似的分割, 然后灰度化, 黑白化, 然后与每个数字特征进行对比, 算出相似度, 然后取相似度最高的数字即可
1 | from PIL import Image |
还是很准的
0x3 代理池
在发送数据的时候发现, 在请求超过50次后永远将404, 这就是ip被ban了, 这里就需要上代理池了
网上有大量免费代理, 采集一下
1 | class ProxyPool: |
连接失败的时候的时候更换ip
1 | pool = ProxyPool() |
0x4 全部代码
主体
1 | import requests |
特征点
1 | {"0": [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255], "1": [255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], "2": [0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255], "3": [0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255], "4": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255], "5": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255], "6": [255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255], "7": [0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], "8": [255, 255, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 255, 255], "9": [255, 255, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255]} |
0x5 题目源码
前端
App.tsx
1 | import React from 'react'; |
Drawer.tsx
1 | import React from "react"; |
后端
views.py
1 | from rest_framework.views import APIView |
utils.py
1 | import random |
models.py
1 | from django.db import models |
这个跳板怎么样
主要涉及知识点:
通过SSRF,访问未授权Mysql数据库,写入Webshell
打开网页,F12发现提示”白蜘蛛”,访问robots.txt
拿到有关内网数据库的一些信息(包括账号,库名,表名,字段名)
SSRF访问未授权MySql数据,可以参考这篇文章:
https://blog.csdn.net/qq_41107295/article/details/103026470
(主要是通过gopher协议,发送TCP数据)
页面输入一些网站,发现是可以访问的。(ban掉了dict和file)
使用gopher协议直接发送数据包,访问未授权MySql,在hint字段里面查看到网站的根目录信息。
接下来两种思路:
- 直接load_file根目录下的flag文件
- 通过into outfile向根目录写入webshell,蚁剑访问,拿到flag
EasyWeb
很简单的SQL注入,B站也有视频,不多说
直接上payload:
1 | -1/**/ununionion/**/seselectlect/**/1,2,database()# //爆库 |
PWN
0x00.Command
在Ubuntu终端执行命令来远程运行程序。
1 | nc 121.41.113.245 10000 |
提示我们输入命令,估计是linux命令。
二话不说把文件丢入IDA分析,主函数如下:
程序大意是让用户输入一个字符串,并且将这个字符串当作linux命令执行,因此我们直接执行”/bin/sh”即可控制远程终端,然后再执行cat flag.txt,即可拿到flag值:flag{aa2ff3bc-88e7-4b08-89b0-3e93a445c5d7}
0x01.Command 2
1 | nc 121.41.113.245 10000 |
这题和上题差不多,都是输入命令然后执行。
不同的是,这次输入的命令长度限制为2字节。
我们可以想到用$0命令来重启终端,相当于执行了/bin/sh。
参考博客。
0x02.pwntools
nc之后说flag藏在了里面,下pwntools即可拿到flag,想到了pwntools的recv可以显示出被\r隐藏的句子
把\n和\r之间的字符串base64解码即可。
0x03.miss_some
让我们输入想要的。。。不知所云。
丢ida瞅瞅:
主函数有俩scanf,一个有&,一个没有。也就是说,我们第一次输入值,会被当成下一次输入的目标地址。比如说第一次输入0x08048052这个地址,那buf变量就保存了这个地址,第二次输入的时候,由于没有&,所以scanf就会把v4变量里的值当成地址,进而让用户对0x08048052地址进行输入。
除此之外我们还注意到,程序中运用到了system函数,而且两个scanf函数之后,发现puts(“/bin/sh”);的代码。这里我们只要将puts的函数地址,改写成system的函数地址,那么系统在执行puts(“/bin/sh”);的时候就会执行system(“/bin/sh”);
要了解如何修改函数调用地址,需要了解got表以及got表的覆写技术。这里只大致解释一下:ELF文件中,用一个表,got(全局偏移表)表,来记录整个程序用到的全局函数名(标识符)及其地址。当程序需要调用函数的时候,就去got表搜这个函数的地址。每个函数第一次被调用时,系统还会将got表重定向到plt表(过程连接表)中,使其根据函数一一对应。所以最终调用的还是plt表里的地址。
因此我们只要向puts的got表中写入system在plt表中的值,即可拿flag。
1 | from pwn import * |
0x04.ROP
rop老套路了。
IDA中shift+F12
双击查看/bin/sh的地址
双击查看system的地址
计算偏移量
0x4-(-0x38)=60
payload如下:
1 | from pwn import * |
这里我们需要注意函数调用栈的结构,如果是正常调用 system 函数,我们调用的时候会有一个对应的返回地址,这里以’bbbb’ 作为虚假的地址,其后参数对应的参数内容。
RE
0x00 . 不会有人看不懂c吧
顾名思义,这是和c相关的逆向,可以直接扔进ida分析程序
程序逻辑也一目了然,简单来说就是,将你的输入与num数组中存在的位置异或,然后放到该位置,最后与程序中存在的数据进行比较,全部一样,则判定为正确的flag。
所以逆向脚本也很简单
1 | a=[125,94,108,48,126, |
flag{n0t_r3ver5e_ez_7han_me!}
0x01 . 没老师教,惨惨
其实题目名和提示都是表示,用来写出这个exe程序的代码是没老师教的
结合我们的日常使用以及分析程序,很容易想到是python代码
例如使用ida查看字符串,有大量py开头的字符
最常见的py打包方法是py2exe和pyinstaller,这里我使用的是pyinstaller
搜索如何反编译pyinstaller可得pyinstaller自带archive_viewer可以反编译
1 | from PyInstaller.utils.cliutils.archive_viewer import run |
这个脚本的可用命令:
1 | U: go Up one level |
我们使用x test,来提取test文件,可以得到.pyc文件
但需要注意的是这个提取出来的pyc可能会缺少文件头,补上即可
再扔进反编译工具可得
1 | Str = '' |
容易看出是凯撒加密密码,但是还是没有flag,为什么呢
是因为出题人太菜了呜呜呜
以为python编译后是保留注释的,其实只保留‘’‘因为这算字符串’‘’,不保留#
也就是说没有了
# Str = zxeedoxeedgxegxe
最后的flag应该是 flag{wubbalubbadubdub}
咚咚咚,dbq大家
CRYPTO
0x00 . pig🐖
根据题目知道是猪圈密码。
解出来是:eatalldaysleepallnight
REPLACE
简单的替换密码(找规律)
明文的每个字母都对应密文里某个特定的字母
(最后少的两个随意组合一下就行)
梨son对数
1 | from Crypto.Util.number import * |
把网鼎杯的数据改小了,用在线网站工具离散对数计算器即可求解
把3373md5加密即可
MISC
0x00 . sounds
根据题目,猜出是个音频文件,改成.mp3后缀听一下,没啥信息。
丢进Audiecy:
查看频谱图:
得到flag。
佬涩披
stegsolve方向键点几下就有了