标题: 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弄崩了,决定视而不见,不挂调试器。