本文为看雪论坛精华文章
看雪论坛作者ID:zackery
$ wget https://www.sudo.ws/dist/sudo-1.8.21.tar.gz
$ tar xzf sudo-1.8.21.tar.gz
$ docker pull aflplusplus/aflplusplus
# 拉取afl++
$ docker run -ti -v /location/of/your/target:/src \
[-v /location/of/your/afl_src/:AFLplusplus \]
aflplusplus/aflplusplus /bin/bash
# 启动docker afl
# 映射代码文件夹,如果本地没有afl++的源代码的话,建议也映射一份,便于后续操作
$ ./configure --prefix=/src/origin_compile
$ make
$ make install
$ cd /src/origin_compile/bin
$ ./sudoedit -s '\' aaaaaaaaaaaaaaa
--- ./src/sudo.c
+++ ./src/sudo.c
@@ -522,9 +524,9 @@
}
ud->sid = getsid(0);
- ud->uid = getuid();
+ ud->uid = 1000;
ud->euid = geteuid();
- ud->gid = getgid();
+ ud->gid = 1000;
ud->egid = getegid();
+++ sudo.c 2023-01-22 01:09:38.175635142 -0800
--- sudo.c_org1 2023-01-22 01:06:27.035319663 -0800
@@ -14,7 +14,6 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+ #include "argv-fuzz-inl.h"
#ifdef __TANDEM
# include <floss.h>
#endif
@@ -134,7 +133,6 @@
int
main(int argc, char *argv[], char *envp[])
{
+ AFL_INIT_ARGV();
int nargc, ok, status = 0;
char **nargv, **env_add;
char **user_info, **command_info, **argv_out, **user_env_out;
#define AFL_INIT_ARGV() \
do { \
\
argv = afl_init_argv(&argc); \
\
} while (0)
······
#define MAX_CMDLINE_LEN 100000
#define MAX_CMDLINE_PAR 50000
static char **afl_init_argv(int *argc) {
static char in_buf[MAX_CMDLINE_LEN];
static char *ret[MAX_CMDLINE_PAR];
char *ptr = in_buf;
int rc = 0;
if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0) {}
while (*ptr && rc < MAX_CMDLINE_PAR) {
ret[rc] = ptr;
if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;
rc++;
while (*ptr)
ptr++;
ptr++;
}
*argc = rc;
return ret;
,
}
$ make clean
$ ./configure --prefix=~/sudo_gdb_test_auth --disable-shared
$ make
$ make install
$ sudo chown root:root ./sudo
$ sudo chmod u+s ./sudo
$ ls -l
$ ./sudo ls
Password:(expecting input)
$ ps -ef |grep sudo
root 206957 206889 0 19:15 pts/4 00:00:00 ./sudo ls
pwndbg> bt
#0 0x00007f1421f7dfd2 in __GI___libc_read (fd=[email protected]entry=5, buf=[email protected]entry=0x7ffd483eb217, nbytes=[email protected]entry=1) at ../sysdeps/unix/sysv/linux/read.c:26
#1 0x00005622b6cac7af in read (__nbytes=1, __buf=0x7ffd483eb217, __fd=5) at /usr/include/x86_64-linux-gnu/bits/unistd.h:44
#2 getln (fd=[email protected]entry=5, buf=[email protected]entry=0x5622b6d0b480 <buf> "", feedback=[email protected]entry=0, bufsiz=256) at ./tgetpass.c:311
#3 0x00005622b6cacbd0 in tgetpass (prompt=0x5622b6e87bb0 "Password: ", timeout=300, flags=0, callback=[email protected]entry=0x7ffd483ebd50) at ./tgetpass.c:178
#4 0x00005622b6c9c81e in sudo_conversation (num_msgs=<optimized out>, msgs=<optimized out>, replies=0x7ffd483eb918, callback=0x7ffd483ebd50) at ./conversation.c:70
#5 0x00005622b6cd8485 in auth_getpass (prompt=0x5622b6e87bb0 "Password: ", timeout=<optimized out>, type=[email protected]entry=1, callback=[email protected]entry=0x7ffd483ebd50) at ./auth/sudo_auth.c:426
#6 0x00005622b6cd88d6 in verify_user (pw=0x5622b6e7e158, prompt=<optimized out>, [email protected]entry=0x5622b6e87bb0 "Password: ", validated=[email protected]entry=2, callback=[email protected]entry=0x7ffd483ebd50) at ./auth/sudo_auth.c:282
#7 0x00005622b6cd93f1 in check_user_interactive (auth_pw=0x5622b6e7e158, mode=<optimized out>, validated=2) at ./check.c:149
#8 check_user (validated=[email protected]entry=2, mode=<optimized out>) at ./check.c:212
#9 0x00005622b6cc2af2 in sudoers_policy_main (argc=[email protected]entry=1, argv=[email protected]entry=0x7ffd483ec1a0, pwflag=[email protected]entry=0, env_add=[email protected]entry=0x0, closure=[email protected]entry=0x7ffd483ebeb0) at ./sudoers.c:423
#10 0x00005622b6cbcfc4 in sudoers_policy_check (argc=1, argv=0x7ffd483ec1a0, env_add=0x0, command_infop=0x7ffd483ebf28, argv_out=0x7ffd483ebf30, user_env_out=0x7ffd483ebf38) at ./policy.c:775
#11 0x00005622b6c9ae57 in policy_check (plugin=0x5622b6d0c000 <policy_plugin>, user_env_out=0x7ffd483ebf38, argv_out=0x7ffd483ebf30, command_info=0x7ffd483ebf28, env_add=0x0, argv=0x7ffd483ec1a0, argc=1) at ./sudo.c:1149
#12 main (argc=[email protected]entry=2, argv=[email protected]entry=0x7ffd483ec198, envp=0x7ffd483ec1b0) at ./sudo.c:247
#13 0x00007f1421e94083 in __libc_start_main (main=0x5622b6c9aa50 <main>, argc=2, argv=0x7ffd483ec198, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7ffd483ec188) at ../csu/libc-start.c:308
#14 0x00005622b6c9c6be in _start () at ./sudo.c:798
-rwsr-xr-x 1 root root 1647712 Jan 23 06:50 sudo
lrwxrwxrwx 1 root root 4 Jan 23 06:50 sudoedit -> sudo
-rwxr-xr-x 1 root root 318384 Jan 23 06:50 sudoreplay
$ echo -ne "sudoedit\0id\0\0" | ./sudo
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
usage: sudo [-AbEHknPS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ...
$ echo "sudo\0id\0\0" | ./sudoedit
usage: sudoedit [-AknS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ...
int
os_init_common(int argc, char *argv[], char *envp[])
{
initprogname(argc > 0 ? argv[0] : "sudo");
#ifdef STATIC_SUDOERS_PLUGIN
preload_static_symbols();
#endif
gc_init();
return 0;
}
void
initprogname(const char *name)
{
# ifdef HAVE___PROGNAME
extern const char *__progname;
if (__progname != NULL && *__progname != '\0')
progname = __progname;
else
# endif
if ((progname = strrchr(name, '/')) != NULL) {
progname++;
} else {
progname = name;
}
/* Check for libtool prefix and strip it if present. */
if (progname[0] == 'l' && progname[1] == 't' && progname[2] == '-' &&
progname[3] != '\0')
progname += 3;
}
--- ../origin_file/progname.c 2023-01-27 01:21:37.829958000 -0800
+++ progname.c 2023-01-27 01:23:42.824771537 -0800
@@ -59,13 +59,6 @@
void
initprogname(const char *name)
{
-# ifdef HAVE___PROGNAME
- extern const char *__progname;
-
- if (__progname != NULL && *__progname != '\0')
- progname = __progname;
- else
-# endif
if ((progname = strrchr(name, '/')) != NULL) {
progname++;
} else {
$ sudo docker run -it \
-v path/to/all_change:/src \
-v path/to/trace_paper_fuzz:/fuzz\
aflplusplus/aflplusplus /bin/bash
$ useradd -u 1000 aflfuzzer
$ cd /src
$ make clean
$ CFLAGS="-g" LDFLAGS="-g" CC=afl-clang-fast ./configure --prefix=/fuzz/release --disable-shared
$ make
$ make install
echo -ne "sudoedit\x00-s\x00\x5c\x00aaaaaaaaaaaaaaaaaaaaaaaaaa\x00\x00" | ./sudo
# 为啥不用直接用\0,我觉得可以,但是我本机解析经常出问题,因此本文全篇都是用\xHH
$ cd /fuzz
$ mkdir {input,output}
$ echo -ne "sudo\x00id\x00\x00" > input/payload1
$ echo -ne "sudoedit\x00id\x00\x00" > input/payload2
afl-fuzz -i input/ -o output/ -D -M Master /fuzz/release/bin/sudo
# 可以创建多个从fuzzer辅助测试
afl-fuzz -i input/ -o output/ -D -S slave1 /fuzz/release/bin/sudo
$ make clean
$ CFLAGS="-g" LDFLAGS="-g" CC=afl-gcc ./configure --prefix=/src/gcc_compile --disable-shared
$ make
$ make install
$ ./sudoedit
__dso_public char *
getenv(const char *name)
{
char *val = NULL;
switch (process_hooks_getenv(name, &val)) {
case SUDO_HOOK_RET_STOP:
return val;
case SUDO_HOOK_RET_ERROR:
return NULL;
default:
return getenv_unhooked(name);
}
}
afl-as.h
"\n"
"/* --- AFL TRAMPOLINE (64-BIT) --- */\n"
"\n"
".align 4\n"
"\n"
"leaq -(128+24)(%%rsp), %%rsp\n"
"movq %%rdx, 0(%%rsp)\n"
"movq %%rcx, 8(%%rsp)\n"
"movq %%rax, 16(%%rsp)\n"
"movq $0x%08x, %%rcx\n"
"call __afl_maybe_log\n"
"movq 16(%%rsp), %%rax\n"
"movq 8(%%rsp), %%rcx\n"
"movq 0(%%rsp), %%rdx\n"
"leaq (128+24)(%%rsp), %%rsp\n"
"\n"
"/* --- END --- */\n"
"\n";
看雪ID:zackery
https://bbs.kanxue.com/user-home-970576.htm
# 往期推荐
球分享
球点赞
球在看
点击阅读原文查看更多