标题: start the inferior without using a shell 创建: 2019-01-17 10:36 链接: https://scz.617.cn/unix/201901171036.txt 大家好,我是以碳基生命形态存在的人形调试器,比较擅长排查一些不作不死的疑难 杂症。今天给大家带来的故事发生在某平行宇宙的某个时间点。 /etc/passwd里有: scz:x:1000:1000:scz,,,:/home/scz:/tmp/sczsh /tmp/sczsh内容如下: -------------------------------------------------------------------------- #!/bin/bash exec /bin/bash "$@" -------------------------------------------------------------------------- 为何出现这种局面无关紧要,不过这并非YY出来的场景,实际遭遇过。此处将整个问 题简化收敛成这么一个例子。以scz登录后env可以看到: SHELL=/tmp/sczsh $ file -b /tmp/some ELF 32-bit LSB pie executable ... readelf -h /tmp/some ELF Header: ... Type: DYN (Shared object file) ... Entry point address: 0x415a ... 现在执行: $ gdb -q -nx /tmp/some (gdb) starti Starting program: /tmp/some Program stopped. 0xb7fd70b0 in ?? () from /lib/ld-linux.so.2 我以为starti之后停在some进程空间中,实际停在bash进程空间中: (gdb) info proc mappings process 10247 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x400000 0x41e000 0x1e000 0x0 /bin/bash 0x41e000 0x4d1000 0xb3000 0x1e000 /bin/bash 0x4d1000 0x528000 0x57000 0xd1000 /bin/bash 0x529000 0x530000 0x7000 0x128000 /bin/bash ... (gdb) info proc status process 10247 Name: bash ... (gdb) info proc stat process 10247 Process: 10247 Exec file: bash ... Start of text: 0x400000 End of text: 0x4d0638 Start of stack: 0xbffff700 (gdb) info proc exe process 10247 exe = '/bin/bash' (gdb) info proc cmdline process 10247 cmdline = '/bin/bash' (gdb) shell ps -f -o pid,user,args PID USER COMMAND 10092 scz /bin/bash 10245 scz \_ gdb -q -nx /tmp/some 10247 scz \_ /bin/bash -c exec /tmp/some 10251 scz \_ ps -f -o pid,user,args 此时想继续调试并断在some进程空间中某地址,"set follow-exec-mode new"没用。 有个歪招: (gdb) catch exec Catchpoint 1 (exec) (gdb) c Continuing. process 10247 is executing new program: /tmp/some Catchpoint 1 (exec'd /tmp/some), 0xb7fd70b0 in ?? () from /lib/ld-linux.so.2 断下来的时候,已经切入新进程映像,前提是exec*()成功。 "catch exec"并不等同于"catch syscall execve",后者断下来时还在原进程映像中, 尚未切入新进程映像。 (gdb) info proc mappings process 10247 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x400000 0x402000 0x2000 0x0 /tmp/some 0x402000 0x417000 0x15000 0x2000 /tmp/some 0x417000 0x423000 0xc000 0x17000 /tmp/some 0x424000 0x426000 0x2000 0x23000 /tmp/some ... (gdb) info proc exe process 10247 exe = '/tmp/some' (gdb) info files ... Entry point: 0x40415a (gdb) shell ps -f -o pid,user,args PID USER COMMAND 10092 scz /bin/bash 10245 scz \_ gdb -q -nx /tmp/some 10247 scz \_ /tmp/some 10255 scz \_ ps -f -o pid,user,args 现在"tb *0x40415a"可以断在some的"Entry point"。 前面都是垃圾,看着很NB但毫无意义。正经套路是: $ gdb -q -nx /tmp/some (gdb) help run ... To start the inferior without using a shell, use "set startup-with-shell off". (gdb) show startup-with-shell Use of shell to start subprocesses is on. 缺省是on,改成off: (gdb) set startup-with-shell off 这样设置之后再run、start、starti,由gdb直接启动被调试进程,不经shell。 (gdb) starti Starting program: /tmp/some Program stopped. 0xb7fd70b0 in ?? () from /lib/ld-linux.so.2 (gdb) info proc mappings process 10261 Mapped address spaces: Start Addr End Addr Size Offset objfile 0x400000 0x402000 0x2000 0x0 /tmp/some 0x402000 0x417000 0x15000 0x2000 /tmp/some 0x417000 0x423000 0xc000 0x17000 /tmp/some 0x424000 0x426000 0x2000 0x23000 /tmp/some ... (gdb) shell ps -f -o pid,user,args PID USER COMMAND 10092 scz /bin/bash 10259 scz \_ gdb -q -nx /tmp/some 10261 scz \_ /tmp/some 10265 scz \_ ps -f -o pid,user,args 程序员的调试技能就是在林林总总的坑中爬出来的。 题外话,个人觉得这种不大不小的坑在CTF比赛中会增加趣味性,不过我是在真实场 景遭遇的,其障碍性后果是副产品。 准备测试用例、写这篇文档时,把SecureCRT弄崩了,决定视而不见,不挂调试器。