装libc困难重重从早上装到了晚上
解决问题的能力还需要提高
过程中学到了很多解决问题的办法
见识了很多share 解决办法 帮忙解决问题的师傅

在此记录 希望能帮到你。

写在前头

发现Ubuntu16.04编译libc 2.23不!会!报!错!
如果想锻炼自己解决问题能力的可以在kali上编译.
我发现于编译完3个月后…
by the way ubuntu 做pwn真的好用.

Linux 编译 LIBC

0x01 Begin

需要低版本的libc学习heap利用技巧
老潘说可以下一个libc自己编译
于是乎 开始了5.1爬坑之旅
在过程中发现百度上关于这方面遇到问题之后的solution太少
谷歌上也没有比较详尽全面的教程。
于是记录一下自己在kali下 编译libc 的过程

0x02 prepare

Time : 2018-04-30
Linux版本信息:

1
Linux Nine 4.6.0-kali1-amd64 #1 SMP Debian 4.6.4-1kali1 (2016-07-21) x86_64 GNU/Linux

Info for glibc-2.23:
下载地址===>http://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.gz
Other libc:
其他版本的libchttp://ftp.gnu.org/gnu/glibc/

0x03 Install

1
2
3
4
5
6
7
cd
mkdir libc && cd libc
wget http://ftp.gnu.org/gnu/glibc/glibc-2.23.tar.gz
tar -xf glibc-2.23.tar.gz
cd glibc-2.23/
mkdir build && cd build
#下载并解压libc 创建build目录 并进入

然后我们来设置一些编译的选项:
x64的

1
2
3
CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og"
CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og"
../configure --prefix=/path/to/install

x32的

1
2
3
4
CC="gcc -m32" CXX="g++ -m32" \
CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og" \
CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og" \
../configure --prefix=/path/to/install --host=i686-linux-gnu

图片来自winesap的社课
图片来自winesap的社课

然后我们开始make

1
make&&make install

如果没问题那就不需要看下面部分了
巴特 一般会遇到问题
下面是我在make过程中遇到的若干问题
前面6个问题是在安装x64时候遇到的

0x00 括号缺失

1
2
3
4
5
6
7
8
9
10
11
12
13
14
setenv.c: In function '__unsetenv':
setenv.c:279:6: error: suggest explicit braces to avoid ambiguous 'else' [-Werror=parentheses]
if (ep != NULL)
^
cc1: all warnings being treated as errors
../o-iterator.mk:9: recipe for target '/builddir/build/BUILD/glibc-arm-linux-gnu-2.23/build-arm-linux-gnu-glibc/stdlib/setenv.o' failed
make[2]: *** [/builddir/build/BUILD/glibc-arm-linux-gnu-2.23/build-arm-linux-gnu-glibc/stdlib/setenv.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/builddir/build/BUILD/glibc-arm-linux-gnu-2.23/glibc-2.23/stdlib'
Makefile:214: recipe for target 'stdlib/subdir_lib' failed
make[1]: *** [stdlib/subdir_lib] Error 2
make[1]: Leaving directory '/builddir/build/BUILD/glibc-arm-linux-gnu-2.23/glibc-2.23'
Makefile:9: recipe for target 'all' failed
make: *** [all] Error 2

reason:

1
2
3
glibc-2.23/nis/nis_call.c与
glibc-2.23/stdlib/setenv.c
大括号缺失

solution:https://bugzilla.redhat.com/show_bug.cgi?id=1312963#c5

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
diff -up glibc-arm-linux-gnu-2.23/glibc-2.23/nis/nis_call.c.gcc61 glibc-arm-linux-gnu-2.23/glibc-2.23/nis/nis_call.c
--- glibc-arm-linux-gnu-2.23/glibc-2.23/nis/nis_call.c.gcc61 2016-02-18 18:54:00.000000000 +0100
+++ glibc-arm-linux-gnu-2.23/glibc-2.23/nis/nis_call.c 2016-05-19 18:44:24.288550322 +0200
@@ -680,6 +680,7 @@ nis_server_cache_add (const_nis_name nam
/* Choose which entry should be evicted from the cache. */
loc = &nis_server_cache[0];
if (*loc != NULL)
+ {
for (i = 1; i < 16; ++i)
if (nis_server_cache[i] == NULL)
{
@@ -690,6 +691,7 @@ nis_server_cache_add (const_nis_name nam
|| ((*loc)->uses == nis_server_cache[i]->uses
&& (*loc)->expires > nis_server_cache[i]->expires))
loc = &nis_server_cache[i];
+ }
old = *loc;
*loc = new;

diff -up glibc-arm-linux-gnu-2.23/glibc-2.23/stdlib/setenv.c.gcc61 glibc-arm-linux-gnu-2.23/glibc-2.23/stdlib/setenv.c
--- glibc-arm-linux-gnu-2.23/glibc-2.23/stdlib/setenv.c.gcc61 2016-02-18 18:54:00.000000000 +0100
+++ glibc-arm-linux-gnu-2.23/glibc-2.23/stdlib/setenv.c 2016-05-19 18:41:09.778640989 +0200
@@ -277,6 +277,7 @@ unsetenv (const char *name)

ep = __environ;
if (ep != NULL)
+ {
while (*ep != NULL)
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
{
@@ -290,6 +291,7 @@ unsetenv (const char *name)
}
else
++ep;
+ }

UNLOCK;

0x01 .symver on common symbols

1
2
3
/tmp/cc8lsExU.s: Error: symbol `loc1@GLIBC_2.2.5' can't be versioned to common symbol
/tmp/cc8lsExU.s: Error: symbol `loc2@GLIBC_2.2.5' can't be versioned to common symbol
/tmp/cc8lsExU.s: Error: symbol `locs@GLIBC_2.2.5' can't be versioned to common symbol

reason:

1
symver is used on common symbol

solution:https://patchwork.ozlabs.org/patch/780067/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
diff --git a/misc/regexp.c b/misc/regexp.c
index 19d76c0..9017bc1 100644
--- a/misc/regexp.c
+++ b/misc/regexp.c
@@ -29,14 +29,17 @@

#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_23)

-/* Define the variables used for the interface. */
-char *loc1;
-char *loc2;
+#include <stdlib.h> /* Get NULL. */
+
+/* Define the variables used for the interface. Avoid .symver on common
+ symbol, which just creates a new common symbol, not an alias. */
+char *loc1 = NULL;
+char *loc2 = NULL;
compat_symbol (libc, loc1, loc1, GLIBC_2_0);
compat_symbol (libc, loc2, loc2, GLIBC_2_0);

/* Although we do not support the use we define this variable as well. */
-char *locs;
+char *locs = NULL;
compat_symbol (libc, locs, locs, GLIBC_2_0);

0x02 Fix warnings from latest GCC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
../sysdeps/ieee754/dbl-64/e_pow.c: In function ‘checkint’:
../sysdeps/ieee754/dbl-64/e_pow.c:469:13: error: << in boolean context, did you mean '<' ? [-Werror=int-in-bool-context]
if (n << (k - 20))
~~^~~~~~~~~~~
../sysdeps/ieee754/dbl-64/e_pow.c:471:17: error: << in boolean context, did you mean '<' ? [-Werror=int-in-bool-context]
return (n << (k - 21)) ? -1 : 1;
~~~^~~~~~~~~~~~
../sysdeps/ieee754/dbl-64/e_pow.c:477:9: error: << in boolean context, did you mean '<' ? [-Werror=int-in-bool-context]
if (m << (k + 12))
~~^~~~~~~~~~~
../sysdeps/ieee754/dbl-64/e_pow.c:479:13: error: << in boolean context, did you mean '<' ? [-Werror=int-in-bool-context]
return (m << (k + 11)) ? -1 : 1;
~~~^~~~~~~~~~~~
cc1: all warnings being treated as errors

reason:

1
2
文件/sysdeps/ieee754/dbl-64/e_pow.c中
对n=0没有检测 在if判断中加上!=0即可解决

solution:https://patchwork.ozlabs.org/patch/680578/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
diff --git a/sysdeps/ieee754/dbl-64/e_pow.c b/sysdeps/ieee754/dbl-64/e_pow.c
index 663fa39..bd758b5 100644
--- a/sysdeps/ieee754/dbl-64/e_pow.c
+++ b/sysdeps/ieee754/dbl-64/e_pow.c
@@ -466,15 +466,15 @@ checkint (double x)
return (n & 1) ? -1 : 1; /* odd or even */
if (k > 20)
{
- if (n << (k - 20))
+ if (n << (k - 20) != 0)
return 0; /* if not integer */
- return (n << (k - 21)) ? -1 : 1;
+ return (n << (k - 21) != 0) ? -1 : 1;
}
if (n)
return 0; /*if not integer */
if (k == 20)
return (m & 1) ? -1 : 1;
- if (m << (k + 12))
+ if (m << (k + 12) != 0)
return 0;
- return (m << (k + 11)) ? -1 : 1;
+ return (m << (k + 11) != 0) ? -1 : 1;
}

0x003 sunrpc/rpc_parse.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ALL  ]      rpc_parse.c: In function 'get_prog_declaration':
[ERROR] rpc_parse.c:543:23: error: '%d' directive writing between 1 and 10 bytes into a region of size 7 [-Werror=format-overflow=]
[ALL ] sprintf (name, "%s%d", ARGNAME, num); /* default name of argument */
[ALL ] ^~
[ALL ] rpc_parse.c:543:20: note: directive argument in the range [1, 2147483647]
[ALL ] sprintf (name, "%s%d", ARGNAME, num); /* default name of argument */
[ALL ] ^~~~~~
[ALL ] rpc_parse.c:543:5: note: 'sprintf' output between 5 and 14 bytes into a destination of size 10
[ALL ] sprintf (name, "%s%d", ARGNAME, num); /* default name of argument */
[ALL ] ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ALL ] cc1: all warnings being treated as errors
[ERROR] make[3]: *** [/Volumes/OSXElCapitan/Users/mrdekk/casesafe/.build/x86_64-ubuntu16.04-linux-gnu/build/build-libc-final/multilib/sunrpc/rpc_parse.o] Error 1
[ERROR] make[3]: *** Waiting for unfinished jobs....
[ERROR] make[2]: *** [sunrpc/others] Error 2
[ERROR] make[1]: *** [all] Error 2

这个还有下个问题的solution从MrDekk的blog上得到
solution:

1
2
3
4
5
6
7
8
9
10
11
--- a/sunrpc/rpc_parse.c
+++ b/sunrpc/rpc_parse.c
@@ -521,7 +521,7 @@ static void
get_prog_declaration (declaration * dec, defkind dkind, int num /* arg number */ )
{
token tok;
- char name[10]; /* argument name */
+ char name[MAXLINESIZE]; /* argument name */

if (dkind == DEF_PROGRAM)
{

0x004 nis/nss_nisplus/nisplus-alias.c

1
2
3
4
5
6
nss_nisplus/nisplus-alias.c:300:12: error: argument 1 null where non-null expected [-Werror=nonnull]
[ERROR] nss_nisplus/nisplus-alias.c:303:39: error: '%s' directive argument is null [-Werror=format-truncation=]
[ERROR] make[3]: *** [/Volumes/OSXElCapitan/Users/mrdekk/casesafe/.build/x86_64-ubuntu16.04-linux-gnu/build/build-libc-final/multilib/nis/nisplus-alias.os] Error 1
[ERROR] make[3]: *** Waiting for unfinished jobs....
[ERROR] make[2]: *** [nis/others] Error 2
[ERROR] make[1]: *** [all] Error 2

solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
diff --git a/nis/nss_nisplus/nisplus-alias.c b/nis/nss_nisplus/nisplus-alias.c
index 7f698b4e6d..509ace1f83 100644
--- a/nis/nss_nisplus/nisplus-alias.c
+++ b/nis/nss_nisplus/nisplus-alias.c
@@ -297,10 +297,10 @@ _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
return NSS_STATUS_UNAVAIL;
}

- char buf[strlen (name) + 9 + tablename_len];
+ char buf[tablename_len + 9];
int olderr = errno;

- snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
+ snprintf (buf, sizeof (buf), "[name=],%s", tablename_val);

nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);

0x005 {安装目录}/etc/ld.so.conf 缺失

1
遇到时候忘记记录

reason:

1
{安装目录}/etc/ld.so.conf 缺失

solution:

1
2
cd /etc/
touch ld.so.conf

0x006 警告

1
2
3
4
5
6
7
8
9
10
11
12
13
14
In file included from regex.c:67:0:
regexec.c: In function ‘check_node_accept_bytes’:
regexec.c:3856:29: error: ‘extra’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
const unsigned char *coll_sym = extra + cset->coll_syms[i];
^~~~~~~~
cc1: all warnings being treated as errors
../o-iterator.mk:9: recipe for target '/root/libc/glibc-2.23/build/posix/regex.o' failed
make[2]: *** [/root/libc/glibc-2.23/build/posix/regex.o] Error 1
make[2]: Leaving directory '/root/libc/glibc-2.23/posix'
Makefile:214: recipe for target 'posix/subdir_lib' failed
make[1]: *** [posix/subdir_lib] Error 2
make[1]: Leaving directory '/root/libc/glibc-2.23'
Makefile:9: recipe for target 'all' failed
make: *** [all] Error 2

reason:

1
2
cc1: all warnings being treated as errors
警告并报错退出编译,这是由于设置了警告提示

solution:

1
2
3
4
5
6
CC="gcc -m32" CXX="g++ -m32" \
CFLAGS="-g -g3 -ggdb -gdwarf-4 -Og -Wno-error" \
CXXFLAGS="-g -g3 -ggdb -gdwarf-4 -Og" \
../configure --prefix=/path/to/install --host=i686-linux-gnu

更改CFLAGS 增加-Wno-error

0x03 End

装libc困难重重从早上装到了晚上
解决问题的能力还需要提高
过程中学到了很多解决问题的办法
见识了很多share 解决办法 帮忙解决问题的师傅

在此记录 希望能帮到你。