[范例]从正在运行的Linux进程中dump出内存内容

参考:
https://colin.guru/index.php?title=Dumping_Ram_From_Running_Linux_Processes

最近看到有个CTF题感觉挺有意思,就是从一个bin中找到一个secret key,然后用来签名session cookies用来怼一个使用go的Web服务器。通常这种类型题的flag都比较直接。可以直接用strings怼这个bin就可以了,然而这次的这个题目中的bin不同,因为有太多杂碎(noise)要过滤了。于是在此我就来展示一下如何用一些基本的Linux命令配合gdb从进程中dump出内存中的信息。
先file一下,

$ file ctf-bin
ctf-bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

发现是64位的Linux可执行文件。
然后strings一下,

$ strings -n 10 ctf-bin | wc | uniq
   71085  106643 2081483

发现字符串太多,还是先不看,再研究深一点吧。
然后先运行一下程序,

$ ./ctf-bin

然后再另一个终端找到这个进程的PID

$ ps -elf | grep ctf-bin
4 S root       6686   5777  0  80   0 -  8403 -      17:02 pts/0    00:00:00 ./ctf-bin
0 S root       6701   6694  0  80   0 -  3179 -      17:02 pts/2    00:00:00 grep ctf-bin

然后cat一下它的内存(太长不看TL;DR)

$ cat /proc/6686/maps
00400000-007bd000 r-xp 00000000 08:01 1727726                            /root/ctf/q3ctf/ctf-bin
007bd000-00bb9000 r--p 003bd000 08:01 1727726                            /root/ctf/q3ctf/ctf-bin
00bb9000-00bdb000 rw-p 007b9000 08:01 1727726                            /root/ctf/q3ctf/ctf-bin
00bdb000-00bff000 rw-p 00000000 00:00 0 
016b2000-016d3000 rw-p 00000000 00:00 0                                  [heap]
c000000000-c000001000 rw-p 00000000 00:00 0 
c81fff0000-c820200000 rw-p 00000000 00:00 0 
...

似乎太多了有点可怕,但是不用害怕。
然后启动gdb,将改进程attach到gdb上。

$ gdb attach 6686

然后就是gdb命令

(gdb) dump memory /root/memory.dump 0xc81fff0000 0xc820200000

解释一下语法:
- "dump memory"是命令
- "/root/memory.dump"是我们想保存dump出的内容的路径。
- 两个hex是内存地址区间,这跟/proc/6686/maps的格式有些不一样。这是以0x开头的而且没有连字符。

然后就是用strings命令找出刚才dump出的文件的字符串,我喜欢最少10个长度的字符串(-n 10)来过滤掉一些无用的信息(noise)。
结果如下:

$ strings -n 10 /root/memory.dump
XDG_VTNR=2
XDG_SESSION_ID=1SHELL=/bin/bash
VTE_VERSION=4201USER=rootSHLVL=1USERNAME=root
LANG=en_US.UTF-8XDG_SEAT=seat0
HOME=/root
LOGNAME=root
...
Thu Feb 4 21:00:57 -0800 2010
aBCdEfJ2cPhLzQ2l111oZMHuADgJQVlkA
Wed Sep 28 17:02:15 EDT 2016
Wed Sep 28 17:02:15 EDT 2016
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
Starting scrum-cookies-server on port 9000.
Starting scrum-cookies-server on port 9000.
Wed Sep 28 17:02:15 EDT 2016 - INFO - main.go:110 - Starting scrum-cookies-server on port 9000.

可以看到好像有个hash值,为了不泄露CTF题的答案,我已经把hash值改了。

总结

好了,你已经找到运行的进程的PID,dump出了那个进程的内存内容,然后用gdb,strings命令找出了有用的数据。

以上翻译自:
https://colin.guru/index.php?title=Dumping_Ram_From_Running_Linux_Processes


Let’s get your hands dirty

Down to business

于是我也想试一下啊,然而我想找一个执行命令之后不退出的进程还蛮难的,最终我想到了apache,然而必须要有客户端与apache建立TCP长连接,如果是那种5xx的错误,比如这个,
就会发现TCP连接建立之后马上又断开了。

cqq@snort-ids:/proc$ tcp|grep "172.18.xx.xx"
sshd     6502     root    3u  IPv4 138454      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:64724 (ESTABLISHED)
sshd     6524      cqq    3u  IPv4 138454      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:64724 (ESTABLISHED)
apache2 13660 www-data   14u  IPv6 179548      0t0  TCP 172.18.yy.yy:80->172.18.xx.xx:53496 (ESTABLISHED)
sshd    18442     root    3u  IPv4 180814      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:52149 (ESTABLISHED)
sshd    18454      cqq    3u  IPv4 180814      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:52149 (ESTABLISHED)
cqq@snort-ids:/proc$ tcp|grep "172.18.xx.xx"
sshd     6502     root    3u  IPv4 138454      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:64724 (ESTABLISHED)
sshd     6524      cqq    3u  IPv4 138454      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:64724 (ESTABLISHED)
sshd    18442     root    3u  IPv4 180814      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:52149 (ESTABLISHED)
sshd    18454      cqq    3u  IPv4 180814      0t0  TCP 172.18.yy.yy:22->172.18.xx.xx:52149 (ESTABLISHED)

于是只能弄一个TCP长连接吧。返回200的那种应该可以。
结果发现还是不行。
于是通过htop漫无目的地找吧,于是还是找apache的主进程吧。
通过htop发信apache的主进程的PID为6900,
于是

cqq@snort-ids:/proc$ sudo gdb attach 6900

(注意:要以root的身份启动,否则可能没有权限。)
然后gdb就开始调试6900进程了,一顿输出啊,几秒之后到达gdb的命令行。
然后dump出heap中的内容。

(gdb) dump memory /root/memory.dump 0x557b9000 0x557fb000
(gdb) dump memory /root/memory2.dump 0x557fb000 0x559eb000

然后在/root目录找到了那两个dump出来的文件,

-rw-r--r--  1 root root 2.0M May 29 20:55 memory2.dump
-rw-r--r--  1 root root 264K May 29 20:54 memory.dump

从任意一个dump中找出10个字符以上的字符串吧。

root@snort-ids:~# strings -n 10 memory.dump
log_config
/usr/lib/apache2/modules/mod_authn_file.so
/usr/lib/apache2/modules/mod_authz_core.0
{U/lib/apache2/modules/mod_authz_host.`
}U/lib/apache2/modules
mod_authz_host.so
oid_section
alg_section
SRVName otherName form
id-on-dnsSRV
Main thread
DEBUG_BACKTRACE_IGNORE_ARGS
PHP_CONFIG_FILE_PATH
E_RECOVERABLE_ERROR

Done :)

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用Frida来检测App进程运行时,可使用frida-dump工具dump内存,可以按照以下步骤进行操作: 1. 首先,你需要下载并安装Frida工具,并打开它。 2. 然后,你需要在Android设备上安装Frida-Server,并启动Frida-Server。可以使用以下命令来启动Frida-Server: ``` frida-server -D ``` 3. 接着,你需要使用Frida来注入一个Javascript脚本到App进程。可以使用以下命令来注入脚本: ``` frida -U -f com.example.app -l script.js --no-pause ``` 其,com.example.app是要注入的App包名,script.js是要注入的Javascript脚本。 4. 在Javascript脚本,你可以使用Frida提供的API来检测App进程是否可被frida-dump工具dump内存。例如,你可以使用以下代码来检测是否有进程调用了frida-dump工具: ``` Interceptor.attach(Module.findExportByName("libc.so", "open"), { onEnter: function(args) { var path = Memory.readUtf8String(args[0]); if (path.indexOf("frida-dump") != -1) { console.log("frida-dump detected!"); } } }); ``` 这段代码会在打开文件时被执行,并检测文件名是否包含“frida-dump”字符串。如果包含,则会输提示信息。 需要注意的是,Frida可以被用于攻击,因为它可以用于修改应用程序的行为。因此,在开发过程,开发人员应该采取一些防范措施,例如使用内存加密技术、禁用日志输等,来保护敏感数据。另外,定期进行安全评估和测试也是必要的,以确保App不存在安全漏洞。 总之,使用Frida来检测App进程运行时,可使用frida-dump工具dump内存是一种有效的方法。开发人员可以采取多种防范措施,来保护App的内存数据安全。同时,定期进行安全评估和测试也是必要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值