继续在ubuntu上学习GDB,今天要学习的是缓冲区溢出。
程序的地址:
GitHub - gedulab/gebypass: bypass password by heap buffer overflow
编译的方法:
gcc -g -O2 -o gebypass gebypass.c
照例设置一下科学shangwang代理:
export https_proxy="https://xxx:8080",为的是能下载符号。
这个代码通俗易懂,就一个.c文件,主要是使用最传统的gets方法,没有判断输入的内容是否超过了缓冲区长度,造成了buffer的输入覆盖了token内存,token内存被填入了刻意准备的值,绕过了鉴权,登录了系统。程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#define GE_MAX_PASSWORD 20
#define GE_TOKEN_SIZE 26
#define GE_TOKEN_PREFIX "#TOKEN#"
#define GE_MINI_PASSWORD 6
int ge_set_token(char* user_token, int size) {
if(size < GE_TOKEN_SIZE)
return -1;
snprintf(user_token, size, "%s:%08d%08d#", GE_TOKEN_PREFIX, getpid(), getpid());
return 0;
}
int ge_check_token(char* user_token, int size) {
int i;
if(strncmp(user_token, GE_TOKEN_PREFIX, strlen(GE_TOKEN_PREFIX))!=0) {
return -1;
}
char* ptr = user_token + strlen(GE_TOKEN_PREFIX)+1;
for(i=0; i<16; i++) {
if(isdigit(*ptr) == 0) {
return -1;
}
ptr++;
}
if(*ptr != '#') {
return -1;
}
return 0;
}
void ge_auth(const char* input, char* user_token, int size) {
// check the password via user database etc.
if(strcmp(input, "$$secret$$") == 0) {
printf("Your password is correct\n");
ge_set_token(user_token, size);
} else {
printf("You have entered the incorrect password\n");
}
}
int main() {
int ret = -1;
char* buffer = (char*)malloc(GE_MAX_PASSWORD); //20
char* token = (char*)malloc(GE_TOKEN_SIZE); //26
puts("Please enter password:");
if(gets(buffer) == NULL || strlen(buffer) < GE_MINI_PASSWORD) {
printf("password is too short %ld\n", strlen(buffer));
goto tag_exit;
}
ge_auth(buffer, token, GE_TOKEN_SIZE);
if(ge_check_token(token, GE_TOKEN_SIZE) != 0) {
printf("Login failed. You are denied.\n");
goto tag_exit;
}
printf("Login succeeded. You are welcome.\n");
puts("You can do privileged operations now...\n");
getchar();
ret = 0;
tag_exit:
free(buffer);
free(token);
return ret;
}
上GDB调试:
gdb ./gebypass
b main -- 设置断点
r -- run起来,会提示下载源码,前面我们设置的proxy,顺利下载。
l --list一下源码,可以看到
(gdb) p buffer
$1 = <optimized out>
(gdb) p token
$2 = <optimized out>
(gdb) n
49 char* buffer = (char*)malloc(GE_MAX_PASSWORD); //20
(gdb) n
50 char* token = (char*)malloc(GE_TOKEN_SIZE); //26
(gdb) n
52 puts("Please enter password:");
(gdb) p bu
buf bufsize build_trtable build_wcs_upper_buffer builtin_modules
buffer build_charclass build_trtable[cold] builtin_aliases
buffer_size build_charclass_op build_wcs_buffer builtin_map
(gdb) p buffer
$3 = 0x5555555592a0 ""
(gdb) p token
$4 = 0x5555555592c0 "" --token紧挨着buffer
查看进程内存:
(gdb) !ps
PID TTY TIME CMD
3138 pts/0 00:00:00 bash
3290 pts/0 00:00:02 gdb
3296 pts/0 00:00:00 gebypass
5612 pts/0 00:00:00 ps
(gdb) !cat /proc/3296/maps
555555554000-555555555000 r--p 00000000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555555000-555555556000 r-xp 00001000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555556000-555555557000 r--p 00002000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555557000-555555558000 r--p 00002000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555558000-555555559000 rw-p 00003000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555559000-55555557a000 rw-p 00000000 00:00 0 [heap]
7ffff7d90000-7ffff7d93000 rw-p 00000000 00:00 0
7ffff7d93000-7ffff7dbb000 r--p 00000000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7dbb000-7ffff7f43000 r-xp 00028000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f43000-7ffff7f92000 r--p 001b0000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f92000-7ffff7f96000 r--p 001fe000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f96000-7ffff7f98000 rw-p 00202000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f98000-7ffff7fa5000 rw-p 00000000 00:00 0
7ffff7fbd000-7ffff7fbf000 rw-p 00000000 00:00 0
7ffff7fbf000-7ffff7fc3000 r--p 00000000 00:00 0 [vvar]
7ffff7fc3000-7ffff7fc5000 r-xp 00000000 00:00 0 [vdso]
7ffff7fc5000-7ffff7fc6000 r--p 00000000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7fc6000-7ffff7ff1000 r-xp 00001000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7ff1000-7ffff7ffb000 r--p 0002c000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7ffb000-7ffff7ffd000 r--p 00036000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7ffd000-7ffff7fff000 rw-p 00038000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
能看到刚刚malloc建立的堆块。
在ge_auth函数设置断点
(gdb) b ge_auth
Breakpoint 2 at 0x555555555460: ge_auth. (2 locations)
(gdb) l ge_auth
file: "/usr/include/x86_64-linux-gnu/bits/stdio2.h", line number: 86, symbol: "ge_auth"
81 }
82
83 __fortify_function int
84 printf (const char *__restrict __fmt, ...)
85 {
86 return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
87 }
88 # elif !defined __cplusplus
89 # define printf(...) \
90 __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
file: "gebypass.c", line number: 37, symbol: "ge_auth"
32 return -1;
33 }
34 return 0;
35 }
36
37 void ge_auth(const char* input, char* user_token, int size) {
38 // check the password via user database etc.
39 if(strcmp(input, "$$secret$$") == 0) {
40 printf("Your password is correct\n");
41 ge_set_token(user_token, size);
(gdb) c
Continuing.
Please enter password:
$$secret$$
Breakpoint 2.1, ge_auth (input=0x5555555592a0 "$$secret$$", user_token=0x5555555592c0 "", size=26) at gebypass.c:37
37 void ge_auth(const char* input, char* user_token, int size) {
下面再跟踪一下异常覆盖的情况:
重新run,这次输入特殊的串:
(gdb) r
Starting program: /home/zxl/gelabs/gtk/bypass/gebypass
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at gebypass.c:47
47 int main() {
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551c0 in main at gebypass.c:47
breakpoint already hit 1 time
(gdb) c
Continuing.
Please enter password:
01234567890abcdefghijklmnopqrstu#TOKEN#:0002381800023638#
第一次少输入了一个0,结果错位了,造成没有到达token的条件,验证失败。所以这个串必须精心设计。
继续单步跟踪,提示输入错误:
(gdb) b ge_auth
Breakpoint 2 at 0x555555555460: ge_auth. (2 locations)
(gdb) c
Continuing.
Please enter password:
01234567890abcdefghijklmnopqrstu#TOKEN#:0002381800023638#
Breakpoint 2.1, ge_auth (input=0x5555555592a0 "01234567890abcdefghijklmnopqrstu#TOKEN#:0002381800023638#",
user_token=0x5555555592c0 "#TOKEN#:0002381800023638#", size=26) at gebypass.c:37
37 void ge_auth(const char* input, char* user_token, int size) {
(gdb) n
39 if(strcmp(input, "$$secret$$") == 0) {
(gdb) p input
$1 = 0x5555555592a0 "01234567890abcdefghijklmnopqrstu#TOKEN#:0002381800023638#"
(gdb) n
86 return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
(gdb) n
43 printf("You have entered the incorrect password\n");
(gdb) l
38 // check the password via user database etc.
39 if(strcmp(input, "$$secret$$") == 0) {
40 printf("Your password is correct\n");
41 ge_set_token(user_token, size);
42 } else {
43 printf("You have entered the incorrect password\n");
44 }
45 }
46
47 int main() {
(gdb)
接下来检查token
(gdb) n
main () at gebypass.c:59
59 if(ge_check_token(token, GE_TOKEN_SIZE) != 0) {
(gdb) l
54 printf("password is too short %ld\n", strlen(buffer));
55 goto tag_exit;
56 }
57 ge_auth(buffer, token, GE_TOKEN_SIZE);
58
59 if(ge_check_token(token, GE_TOKEN_SIZE) != 0) {
60 printf("Login failed. You are denied.\n");
61 goto tag_exit;
62 }
63 printf("Login succeeded. You are welcome.\n");
(gdb) n
63 printf("Login succeeded. You are welcome.\n");
(gdb) p token
$2 = 0x5555555592c0 "#TOKEN#:0002381800023638#"
token值符合要求。
(gdb) p buffer --超出了20个字节
$3 = 0x5555555592a0 "01234567890abcdefghijklmnopqrstu#TOKEN#:0002381800023638#"
(gdb) p token
$4 = 0x5555555592c0 "#TOKEN#:0002381800023638#"
重新运行,认识堆。ptmalloc的堆管理方式,有个一个主场地 main_arena
Breakpoint 1, main () at gebypass.c:47
47 int main() {
(gdb) p main_arena --开始主场地大部分是0,
$5 = {mutex = 0, flags = 0, have_fastchunks = 0, fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, top = 0x0,
last_remainder = 0x0, bins = {0x0 <repeats 254 times>}, binmap = {0, 0, 0, 0}, next = 0x7ffff7f96ac0 <main_arena>,
next_free = 0x0, attached_threads = 1, system_mem = 0, max_system_mem = 0}
(gdb) p &main_arena --它本身在glibc中
$6 = (struct malloc_state *) 0x7ffff7f96ac0 <main_arena>
(gdb) !ps
PID TTY TIME CMD
3138 pts/0 00:00:00 bash
5884 pts/0 00:00:03 gdb
6063 pts/0 00:00:00 gebypass
6358 pts/0 00:00:00 ps
(gdb) !cat /proc/6063/maps
555555554000-555555555000 r--p 00000000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555555000-555555556000 r-xp 00001000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555556000-555555557000 r--p 00002000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555557000-555555558000 r--p 00002000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555558000-555555559000 rw-p 00003000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
7ffff7d90000-7ffff7d93000 rw-p 00000000 00:00 0
7ffff7d93000-7ffff7dbb000 r--p 00000000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7dbb000-7ffff7f43000 r-xp 00028000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f43000-7ffff7f92000 r--p 001b0000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f92000-7ffff7f96000 r--p 001fe000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f96000-7ffff7f98000 rw-p 00202000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f98000-7ffff7fa5000 rw-p 00000000 00:00 0
7ffff7fbd000-7ffff7fbf000 rw-p 00000000 00:00 0
7ffff7fbf000-7ffff7fc3000 r--p 00000000 00:00 0 [vvar]
7ffff7fc3000-7ffff7fc5000 r-xp 00000000 00:00 0 [vdso]
7ffff7fc5000-7ffff7fc6000 r--p 00000000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7fc6000-7ffff7ff1000 r-xp 00001000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7ff1000-7ffff7ffb000 r--p 0002c000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7ffb000-7ffff7ffd000 r--p 00036000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffff7ffd000-7ffff7fff000 rw-p 00038000 08:02 4215471 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
(gdb) s
49 char* buffer = (char*)malloc(GE_MAX_PASSWORD); //20
(gdb) s
Download failed: 无效的参数. Continuing without source file ./malloc/./malloc/malloc.c.
0x00007ffff7e40654 in __GI___libc_malloc (bytes=bytes@entry=20) at ./malloc/malloc.c:3301
warning: 3301 ./malloc/malloc.c: 没有那个文件或目录 --没有源码,看不了。
需要下载源码:
zxl@qwq:~$ cat /etc/apt/sources.list
# Ubuntu sources have moved to /etc/apt/sources.list.d/ubuntu.sources
zxl@qwq:~$ cat /etc/apt/sources.list.d/ubuntu.sources
Types: deb deb-src
URIs: http://mirrors.huaweicloud.com/repository/ubuntu/
Suites: noble noble-updates noble-security noble-backports
Components: main restricted universe
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
说明已经设置了HW的网站作为下载网站。deb-src
开始下载:
zxl@qwq:~$ sudo apt source lib
[sudo] zxl 的密码:
正在读取软件包列表... 完成
E: 无法找到与 lib 对应的源代码包
zxl@qwq:~$ sudo apt source glibc
正在读取软件包列表... 完成
提示:glibc 的打包工作被维护于以下位置的 Git 版本控制系统中:
https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/glibc
请使用:
git clone https://git.launchpad.net/~ubuntu-core-dev/ubuntu/+source/glibc
获得该软件包的最近更新(可能尚未正式发布)。
需要下载 19.0 MB 的源代码包。
获取:1 http://mirrors.huaweicloud.com/repository/ubuntu noble-updates/main glibc 2.39-0ubuntu8.3 (dsc) [9,213 B]
获取:2 http://mirrors.huaweicloud.com/repository/ubuntu noble-updates/main glibc 2.39-0ubuntu8.3 (tar) [18.5 MB]
获取:3 http://mirrors.huaweicloud.com/repository/ubuntu noble-updates/main glibc 2.39-0ubuntu8.3 (asc) [833 B]
获取:4 http://mirrors.huaweicloud.com/repository/ubuntu noble-updates/main glibc 2.39-0ubuntu8.3 (diff) [463 kB]
已下载 19.0 MB,耗时 2秒 (9,716 kB/s)
dpkg-source: info: extracting glibc in glibc-2.39
dpkg-source: info: unpacking glibc_2.39.orig.tar.xz
dpkg-source: info: unpacking glibc_2.39-0ubuntu8.3.debian.tar.xz
dpkg-source: info: using patch list from debian/patches/series
dpkg-source: info: applying git-updates.diff
dpkg-source: info: applying locale/check-unknown-symbols.diff
dpkg-source: info: applying locale/locale-print-LANGUAGE.diff
dpkg-source: info: applying locale/LC_IDENTIFICATION-optional-fields.diff
dpkg-source: info: applying localedata/sort-UTF8-first.diff
dpkg-source: info: applying localedata/supported.diff
dpkg-source: info: applying localedata/locale-eu_FR.diff
......
dpkg-source: info: applying CVE-2024-33600_2.patch
dpkg-source: info: applying CVE-2024-33601_33602.patch
W: 由于文件'glibc_2.39-0ubuntu8.3.dsc'无法被用户'_apt'访问,已脱离沙盒并提权为根用户来进行下载。 - pkgAcquire::Run (13: 权限不够)
zxl@qwq:~$ ls
公共的 examples.desktop idea orange
模板 gegdb IdeaProjects pg
视频 gelabs java
图片 glibc-2.39 lmos rust
文档 glibc_2.39-0ubuntu8.3.debian.tar.xz
malloc在:q:~/glibc-2.39/malloc$ pwd
/home/zxl/glibc-2.39/malloc
回到GDB设置源码路径
(gdb) bt
#0 0x00007ffff7e40654 in __GI___libc_malloc (bytes=bytes@entry=20) at ./malloc/malloc.c:3301
#1 0x00005555555551d2 in main () at gebypass.c:49
(gdb) dir /home/zxl/glibc-2.39/malloc
Source directories searched: /home/zxl/glibc-2.39/malloc:$cdir:$cwd
(gdb) l --再调用list就可以看到源码了。不错
3296 void *victim;
3297
3298 _Static_assert (PTRDIFF_MAX <= SIZE_MAX / 2,
3299 "PTRDIFF_MAX is not more than half of SIZE_MAX");
3300
3301 if (!__malloc_initialized)
3302 ptmalloc_init ();
3303 #if USE_TCACHE
3304 /* int_free also calls request2size, be careful to not pad twice. */
3305 size_t tbytes = checked_request2size (bytes);
可以跟着一下malloc的细节
分配完成后,再看堆空间,就多了
(gdb) !cat /proc/6063/maps
555555554000-555555555000 r--p 00000000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555555000-555555556000 r-xp 00001000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555556000-555555557000 r--p 00002000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555557000-555555558000 r--p 00002000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555558000-555555559000 rw-p 00003000 08:02 3969804 /home/zxl/gelabs/gtk/bypass/gebypass
555555559000-55555557a000 rw-p 00000000 00:00 0 [heap]
7ffff7d90000-7ffff7d93000 rw-p 00000000 00:00 0
7ffff7d93000-7ffff7dbb000 r--p 00000000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7dbb000-7ffff7f43000 r-xp 00028000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f43000-7ffff7f92000 r--p 001b0000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f92000-7ffff7f96000 r--p 001fe000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f96000-7ffff7f98000 rw-p 00202000 08:02 4219286 /usr/lib/x86_64-linux-gnu/libc.so.6
7ffff7f98000-7ffff7fa5000 rw-p 00000000 00:00 0
再看主场地也变化了:
(gdb) p main_arena
$8 = {mutex = 0, flags = 0, have_fastchunks = 0, fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
top = 0x5555555592e0, last_remainder = 0x0, bins = {0x7ffff7f96b20 <main_arena+96>, 0x7ffff7f96b20 <main_arena+96>,
0x7ffff7f96b30 <main_arena+112>, 0x7ffff7f96b30 <main_arena+112>, 0x7ffff7f96b40 <main_arena+128>,
0x7ffff7f96b40 <main_arena+128>, 0x7ffff7f96b50 <main_arena+144>, 0x7ffff7f96b50 <main_arena+144>,
0x7ffff7f96b60 <main_arena+160>, 0x7ffff7f96b60 <main_arena+160>, 0x7ffff7f96b70 <main_arena+176>,
0x7ffff7f96b70 <main_arena+176>, 0x7ffff7f96b80 <main_arena+192>, 0x7ffff7f96b80 <main_arena+192>,
0x7ffff7f96b90 <main_arena+208>, 0x7ffff7f96b90 <main_arena+208>, 0x7ffff7f96ba0 <main_arena+224>,
0x7ffff7f96ba0 <main_arena+224>, 0x7ffff7f96bb0 <main_arena+240>, 0x7ffff7f96bb0 <main_arena+240>,
0x7ffff7f96bc0 <main_arena+256>, 0x7ffff7f96bc0 <main_arena+256>, 0x7ffff7f96bd0 <main_arena+272>,
0x7ffff7f96bd0 <main_arena+272>, 0x7ffff7f96be0 <main_arena+288>, 0x7ffff7f96be0 <main_arena+288>,
0x7ffff7f96bf0 <main_arena+304>, 0x7ffff7f96bf0 <main_arena+304>, 0x7ffff7f96c00 <main_arena+320>,
0x7ffff7f96c00 <main_arena+320>, 0x7ffff7f96c10 <main_arena+336>, 0x7ffff7f96c10 <main_arena+336>,
0x7ffff7f96c20 <main_arena+352>, 0x7ffff7f96c20 <main_arena+352>, 0x7ffff7f96c30 <main_arena+368>,
实验的原理:如何造特殊字符串:这就不讲了,自己体会一下:
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/zxl/gelabs/gtk/bypass/gebypass
Downloading separate debug info for system-supplied DSO at 0x7ffff7fc3000
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at gebypass.c:47
47 int main() {
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005555555551c0 in main at gebypass.c:47
breakpoint already hit 1 time
2 breakpoint keep y <MULTIPLE>
2.1 y 0x0000555555555460 in ge_auth at gebypass.c:37
2.2 y 0x000055555555547f in ge_auth at /usr/include/x86_64-linux-gnu/bits/stdio2.h:86
(gdb) c
Continuing.
Please enter password:
1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
Breakpoint 2.1, ge_auth (input=0x5555555592a0 "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
user_token=0x5555555592c0 "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", size=26) at gebypass.c:37
37 void ge_auth(const char* input, char* user_token, int size) {
(gdb) s
39 if(strcmp(input, "$$secret$$") == 0) {
(gdb) b ge_check_token
Breakpoint 3 at 0x5555555553f0: file gebypass.c, line 19.
(gdb) c
Continuing.
You have entered the incorrect password
Breakpoint 3, ge_check_token (user_token=user_token@entry=0x5555555592c0 "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", size=size@entry=26)
at gebypass.c:19
19 int ge_check_token(char* user_token, int size) {
(gdb)
valgrind工具:
q:~/gelabs/gtk/bypass$ sudo apt update
[sudo] zxl 的密码:
命中:1 http://mirrors.huaweicloud.com/repository/ubuntu noble InRelease
命中:2 http://mirrors.huaweicloud.com/repository/ubuntu noble-updates InRelease
命中:3 http://mirrors.huaweicloud.com/repository/ubuntu noble-security InRelease
命中:4 http://mirrors.huaweicloud.com/repository/ubuntu noble-backports InRelease
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
有 10 个软件包可以升级。请执行 ‘apt list --upgradable’ 来查看它们。
zxl@qwq:~/gelabs/gtk/bypass$ sudo apt install valgrind
正在读取软件包列表... 完成
正在分析软件包的依赖关系树... 完成
正在读取状态信息... 完成
wq:~/gelabs/gtk/bypass$ valgrind --version
valgrind-3.22.0
zxl@qwq:~/gelabs/gtk/bypass$ valgrind ./gebypass
==7220== Memcheck, a memory error detector
==7220== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==7220== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==7220== Command: ./gebypass
==7220==
Please enter password:
1111111111112222222222222222222222333333333333333333333333333333333
==7220== Invalid write of size 8
==7220== at 0x4850643: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x48F8FE3: memcpy (string_fortified.h:29)
==7220== by 0x48F8FE3: _IO_getline_info (iogetline.c:96)
==7220== by 0x48F91DD: gets (iogets.c:54)
==7220== by 0x1091F7: main (gebypass.c:53)
==7220== Address 0x4a87050 is 16 bytes inside a block of size 20 alloc'd
==7220== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x1091D1: main (gebypass.c:49)
==7220==
==7220== Invalid write of size 8
==7220== at 0x485064B: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x48F8FE3: memcpy (string_fortified.h:29)
==7220== by 0x48F8FE3: _IO_getline_info (iogetline.c:96)
==7220== by 0x48F91DD: gets (iogets.c:54)
==7220== by 0x1091F7: main (gebypass.c:53)
==7220== Address 0x4a87058 is 4 bytes after a block of size 20 alloc'd
==7220== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x1091D1: main (gebypass.c:49)
==7220==
==7220== Invalid write of size 8
==7220== at 0x4850653: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x48F8FE3: memcpy (string_fortified.h:29)
==7220== by 0x48F8FE3: _IO_getline_info (iogetline.c:96)
==7220== by 0x48F91DD: gets (iogets.c:54)
==7220== by 0x1091F7: main (gebypass.c:53)
==7220== Address 0x4a87060 is 12 bytes after a block of size 20 alloc'd
==7220== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x1091D1: main (gebypass.c:49)
==7220==
==7220== Invalid write of size 8
==7220== at 0x4850691: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x48F8FE3: memcpy (string_fortified.h:29)
==7220== by 0x48F8FE3: _IO_getline_info (iogetline.c:96)
==7220== by 0x48F91DD: gets (iogets.c:54)
==7220== by 0x1091F7: main (gebypass.c:53)
==7220== Address 0x4a87068 is 20 bytes after a block of size 20 alloc'd
==7220== at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x1091D1: main (gebypass.c:49)
==7220==
valgrind: m_mallocfree.c:304 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 96, hi = 3689348814741910323.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata. If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away. Please try that before reporting this as a bug.
host stacktrace:
==7220== at 0x58044A9A: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x58044BDF: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x58044D75: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x5804EDB8: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x5803CDCA: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x5803B3E7: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x5803FFD0: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x5803A260: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x58010887: ??? (in /usr/libexec/valgrind/memcheck-amd64-linux)
==7220== by 0x1002E874AC: ???
==7220== by 0x1002DA9F0F: ???
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable (lwpid 7220)
==7220== at 0x48506E3: memcpy@GLIBC_2.2.5 (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==7220== by 0x48F8FE3: memcpy (string_fortified.h:29)
==7220== by 0x48F8FE3: _IO_getline_info (iogetline.c:96)
==7220== by 0x48F91DD: gets (iogets.c:54)
==7220== by 0x1091F7: main (gebypass.c:53)
client stack range: [0x1FFEFFE000 0x1FFF000FFF] client SP: 0x1FFEFFFF18
valgrind stack range: [0x1002CAA000 0x1002DA9FFF] top usage: 18232 of 1048576
Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.
If that doesn't help, please report this bug to: www.valgrind.org
In the bug report, send all the above text, the valgrind
version, and what OS and version you are using. Thanks.