花了两天终于做出了一道题, 想起初中花两小时做数学题的快感了
这题是要逆向提权攻击,获取系统权限之后查看/data/flag 里的内容
nc连上服务器,服务器会应答任何我输进去的字符,比如我输入hello 服务器返回我hello
猜测这个程序就是 getchar() 之后再 putchar
这里就可能有格式化字符漏洞:
比如printf() 有%d, %s,%x之类的参数,作用是以某种格式输出后面地址上的内容
那这句话底层究竟干了些什么呢
比如这句话 printf("%d", &i)
, 它把 i
的地址压入栈, 再调用显示部分的函数.
但其实printf并不关心你有没有真正的传入一个 &i
, 它就是在栈上找一个块内容打印出来. 那如果我没有传最后一个参数呢? 那我就能读到栈上的内容了!
比如 printf("%x")
它打印出来的就是 栈顶指针 之后的第一个字节
这里可以尝试对着服务器输入 AAAA %x %x %x %x %x %x
打印出来的是AAAA
200
f7737c20
0
41414141
25207825
78252078
这里发现里面有 41414141
这正是前面的 AAAA
题目要求我访问服务器的某个文件, 那之后要做的是getshell. 把这个程序丢到ida里, 分析发现刚好有个 call system 的函数. 我要调用这个函数, 有两个思路.
一个是修改printf所在函数的返回地址,把它return到call system上去; 一个是修改printf()后面一个函数的调用地址, 后面有个puts(). 把它修改成geyshell()。
不过第一个失败了,因为我虽然可以知道返回地址离输入位置差多远,但因为这个是在栈上的,无法确定绝对地址, 每次执行 地址都不一样(要是多个循环就可以了)
printf 有些不常见的格式类型 :
%n 到目前为止所写的字符数, 可以用来把一个int型的值写到指定的地址中
参考 https://ctf-wiki.github.io/ctf-wiki/pwn/linux/fmtstr/fmtstr_intro/
就可以修改任意位置的内存
信息安全真有趣hhh