funcanary
1 | funcanary: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=cc48b58555840ef369e5cd0f23a7e8779c021af7, for GNU/Linux 3.2.0, stripped |
- 64位,dynamically,全开
漏洞分析
1 | unsigned __int64 pwn() |
- 栈溢出
1 | void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) |
- 多进程可以爆破 canary
1 | int sub_1229() |
- 有后门
入侵思路
先爆破 canary,然后打栈
完整 exp:
1 | # -*- coding:utf-8 -*- |
shaokao
1 | shaokao: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=2867805c3d477c70c169e3106f70255b7b4e8ffa, for GNU/Linux 3.2.0, not stripped |
- 64位,statically,Partial RELRO,Canary,NX
漏洞分析
1 | __int64 chuan() |
- 负数溢出
1 | __int64 gaiming() |
- 栈溢出
入侵思路
通过负数溢出绕过获取栈溢出,直接 ROP
完整 exp:
1 | # -*- coding:utf-8 -*- |
shellwego
1 | pwn: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=SuxJivkd2dvJbgrdOCZT/N0LJWS-KaWam2n_aHm00/XCCoLNUmWNjMS_l2-7QG/Mo580T0hsQ-JQlJwgRB_, stripped |
- 64位,statically,NX
程序分析
GO 语言的逆向
在执行命令之前需要先绕过加密,核心加密代码在如下函数中:
1 | _QWORD *__fastcall flnall(__int64 a1, __int64 a2) |
逆向脚本如下:
1 | import base64 |
- 结果:S33UAga1n@#!
单步调试程序可以发现验证命令为:cert nAcDsMicN S33UAga1n@#!
漏洞分析
漏洞点在 echo 命令中:
echo 命令拥有一片 0x200 大小的缓冲区,并且限制了输出长度的 0x200
但是该 echo 命令可以将多个以空格为间隔的字符串进行拼接,并统一放入缓冲区中,echo 只对单一的一个字符串进行了长度检查,因此可以使用 echo xxxx xxxx 的形式进行栈溢出
- PS:这里存在一个小问题,在栈溢出的过程中可能会覆盖程序的关键指针从而导致段错误,不过程序提供了 + 字符来处理这个问题(在覆盖数据时,程序会跳过 + 字符)
入侵思路
通过这一个栈溢出就可以打 ROP,执行 syscall 就可以了(直接写入 /bin/sh
即可,该程序的栈随机化比较轻微,有概率命中 /bin/sh
的地址)
完整 exp 如下:
1 | # -*- coding:utf-8 -*- |
talkbot
1 | GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.\n |
1 | pwn: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9201a3cb37f7572f96499f58c70901a874591275, for GNU/Linux 3.2.0, stripped |
- 64位,dynamically,全开
1 | line CODE JT JF K |
漏洞分析
1 | void __fastcall dele(__int64 index) |
- UAF
入侵思路
开了沙盒,因此需要打堆上 ORW,不过在此之前需要先绕过一个加密
逆向了很久也得不出加密逻辑,后来观察加密代码感觉有点像反序列化(比赛时脑袋有点糊了,没有凑出反序列化的格式)
1 | void __fastcall __noreturn main(__int64 a1, char **a2, char **a3) |
由于这不是传统的 protobuf 程序,因此不能使用 pbtk
通过逆向 + 调试 + 猜测,得出了以下格式:
1 | syntax = "proto3"; |
- 这里补充几个合理的 protobuf 序列:
1 | b'\x08\x02\x10\x04\x18\xa0\x02"\x90\x01aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' |
0x08 0x10 0x18
分别代表actionid msgidx msgsize
的累加长度0x90
则代表msgcontent
的长度
拥有 UAF 可以轻松完成泄露
然后写入 ORW,计算好偏移地址
最后打一个 tcache attack,劫持 free_hook 为 malloc_gadget
1 | 0x0000000000151990: mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20]; |
完整 exp 如下:
1 | # -*- coding:utf-8 -*- |
login
本题目无附件
入侵思路
比赛时发现有无限栈溢出,于是猜测是多线程覆盖 TLS 的那种 canary 题目
然后发现好像只能爆破 PIN 值,于是想找个弱密码字典进行爆破(没有找到合适的)
后来看 wp 才发现这题要打侧信道(比赛时想到了这个方法,但由于对侧信道的理解不够深刻,于是忽略了这个方法)
侧信道攻击:当输入的 PIN 值的某一位与正确 PIN 值的对应位不同时,可能会导致系统的某些操作或计算需要更多的时间,通过观察时间戳的差异,攻击者可以推断出某一位是否正确
由于题目环境已经关闭,不能对 exp 进行调试
非完整 exp 如下:
1 | from pwn import * |