Skip to content

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