24-03-24
本周学习总结
复现一点陈年老题。(Word*) Ptr -> pw
全局常量声明:新手上路,文章内容仅是由教程观点和自己总结获得,仅供参考。
一、下次一定
下次一定。
二、[Easy?]–write1
Check:

64位程序,开启canary和NX
Ida:
do_something:

Door:

细节题。程序中有一个无限输入,但是并不在栈上,所以没什么用,程序也没有可暴露canary的地方,唯一可用的就是一个后门函数。
在do_something函数的第19行我们发现有可在栈上可写的语句,我们可以使用它去改变rip的地址。首先这里就要注意两个问题,首先就是指针v2原本应该是指向int64的指针,在这里被改为了指向BYTE(字节)的指针,所有这里的如果+1的话不是跳8个字节,而是跳1个字节,其次这里不是直接赋值,而是在原先值的基础是相加。
通过gdb调试我们可以发现rip正常的地址是比后门函数的地址要高的,所以我们输入地址时应输入负数,而且由于v2变成指向字节的指针,我们一次只能改1个字节的数据。我们需要通过两次来进行完全修改,偏移分别为0x28和0x29。
但是在修改完后我们仍然发现无法执行shell,这里是因为如果写的直接是后门函数的地址的话会出现栈对齐问题,我们直接跳过一些指令直接从真正有意义的地方开始执行就可以了。(我就说直接复制/bin/sh那里的地址更好吧)
exp:
1 | |
shell:

三、[Medium]–write2
Check:

64位程序,开启canary、PIE和RELRO。
ida:
do_something:

无system和”/bin/sh\x00”,因为没有开启NX保护,可以考虑在栈上写shellcode。但是在实际操作后你会发现刚好少两个字节的写入。
解决办法很多,这里采用最笨的办法,利用v2在rip后面布置shellcode,通过改写rip跳转。
exp:
1 | |
shell:

四、[Medium]–[NKCTF2024]maimai分数查看器
check:

64位程序,保护全开。
ida:
main:


funA:


funC:

funB:

key:

我们需要在funA中输入40组数据来保证在funB中比较时num>num2,这里直接用最高分数数据15.0 “SSS+”。
在funB中我们发现了字符串格式化漏洞,可以泄漏栈上任意地址。在key中我们发现了0x48的溢出。因为整个程序处于一个whlie死循环中,我们可以通过多次字符串格式化漏洞来暴露__libc_start_main和canary,然后通过libc中控制寄存器的代码片段来getshell。
通过这种方法确实可以getshell,但是在获取远程shell后我们发现没有root权限来查看flag。
简直就是

我们只好通过ORW来获取flag,但是这样有有个问题,那就是溢出不够用了,就算是最短的ORW办法也是少了0x8字节的溢出,所以我们还需要通过字符串格式化漏洞暴露PIE和rbp,获得在栈上和bss段上写的权利。
因为溢出是刚好够写一个read,我们直接在通过rbp在栈上找到rsp+0x8的位置继续写,接上一个无限ROP,
这样就可以成功ORW。
exp:
1 | |
flag(本地):

下周学习计划
| 应该要做的事情 |
6
学习感受
6