microcorruption
bin新手的iot pwn初试炼。
注:本文所有单体数字均为16进制
这是个啥
microcorruption是一个基于msp430单片机的在线pwn靶场,其主要优势有以下几个:
- 在网页端集成了调试台,强制锻炼命令行调试能力;
- 没有反汇编,强制锻炼读汇编码的能力;
- 16位risc架构,寄存器和栈综合传参;
- 有硬件接口,目标明确途径多样,强调文档学习能力;
- 题目考点单一,非常适合用来抠基础原理。
前置知识
调试命令
用的命令集基本上是gdb那一套,但因为实时内存转存,没做内存显示,常用有以下
1 | c(continue) : 继续执行 |
架构基础
- 使用risc-v架构,十六位小端,软件寄存器传参,调用硬件中断时是栈传参。
- 主程序入口text段4400,bss段位置2400,堆区5000以上,一页100byte
- 要求2字节对齐
应用基础
通过调用INT函数并传入对应参数实现硬件中断交互。
具体参数
1 | #10:打开DEP |
汇编规定
- 语法风格:op source dst
- Rx寄存器,@Rx对寄存器寻址(拓展用法:(t)Rx{asm}==Rx[t]{C}),@Rx+ 寻址后寄存器自增。
- #c是立即数,c是间接寻址,c{asm}==r0[c]{c}
- flag: Z(零置位) ,N(负置位) ,C(溢出置位)
部分题目WP
本部分是这周做题的大致总结,具体的做题心路历程与收获会在做完最后两个题后汇总投合天
雷克雅未克(bss段放置函数)
本题主要是在数据段内预设了函数并执行,如何读到这段程序是本题主要问题。
方式1
单步执行读右上角的当前指令。
方式2
跟进程序,发现调用了2400位置,运行起来之后使用read命令读取内存,发现函数大约在180长度左右,丢进反编译器,寻找cmp命令。然后将程序运行到对应位置,发现比较的位置是我们的输入,注意大小端即可解决输入问题。
input:9d86
注:十六进制输入用数字,字符输入用字符串
怀特豪斯/蒙德维地亚(栈溢出)
发现两个题没啥大区别(内 部 重 构),所以直接判断溢出长度16,找gadget,发现在4460处调用了int,栈传参,直接伪造栈帧6044 7f00 即可。
input:4141414141414141414141414141414160447f
约翰内斯堡(canary)
这里canary是固定压栈进去的,所以注意一下输入构造就好了
input:4141414141414141414141414141414141184644
亚的斯亚达巴(格式化字符串漏洞初步)
核心原理是%n这个控制符会将输出字符数写入下一个参数,利用这一点伪造栈帧即可。
input:503c2569256e
阿尔及尔(堆溢出)
堆的结构:bk+fd+size(vilid)+memory,开辟内存时多个块顺序开放,而free的时候需要合并,通过free函数即可发现如果覆盖下一个块的基址,块的元数据被篡改的情况下,就可以执行一次任意地址写,从而达成攻击。
input1:616161616161616161616161444462450100
input2:<blank>
符拉迪沃斯托克(ASLR)
通过printf泄露printf的基址,然后再通过相对位置解决问题。
input1:"%x%x"
input2:"AAAAAAAA"+(printfadd+0x182)(小端)+"AA"+7f00
班加罗尔(DEP)
设置栈所在的页为可写(正在尝试有没有绕过栈不可执行的方案)
input:324000ffb01210006161616161616161ba443f000000ee3f
(shellcode+8字符填充+栈执行函数(取压栈后的位置)+page number+0000+shellcode_addr)
切尔诺贝利(高级堆溢出)
这个题卡在了对free的认知不够以及对堆块伪造的认知上,做出来再来补。