奇怪,Linux 3.11.2-1-ARCH x86_64 居然还是可执行堆栈?

11 篇文章 0 订阅
6 篇文章 0 订阅

这个是系统架构,下面是测试代码「hello.c」:

char shellCode[] = "\xeb\x1a\x5e\x48\x31\xff\x48\x31\xd2\x48\x31\xc0\x66\xff\xc7\xb2\x0d\xb0\x01\x0f\x05\x48\x31\xff\xb0\x3c\x0f\x05\xe8\xe1\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x0a";

int
main (void) {
        long p;
        *(&p+2) = (long)shellCode;
        return 0;
}

奇怪了就,gcc 生成目标文件,然后看了下节头:


明摆着就就一个text 段可执行,居然真把shellcode 给执行了,这货明摆着在「.data」 里:



话说这地方真是费解了,写这个程序主要是看BINARY HACKS 的GNU 编程HACK 那一章,说2.6 之后都已经打了补丁,成了不可执行栈了,需要用objcopy 为数据所在的段增加X 标记才可以。于是手贱参考shellcode 的原理试了下,结果成了这个样子。。。

有空再回头看下,今晚要补完《濑户之花嫁》。


另外自己写的那段shellcode 是X86_64 版本的,就是调用了个write 系统调用,吐槽下X86_64 汇编系统调用的寄存器约定改的。。参数上来就用到rdi,给di 赋值1,为了避免产生\x0 都要换成xorq 和incw。。。

对于字符串的地址的运行时定位,我用的下面的方法确定的地址:

_start:
        jmp     begin
shellCode:
        popq    %rsi            # 出栈字符串地址 
        # 操作字符串的代码
begin:
        call shellCode          # 利用call 指令压栈的特性把字符串地址压栈
        .ascii "string"
完了之后编译下,并且反汇编得到shellcode:

# as -o write.o write.s
# ld -o write write.o
# echo -e "\\\x""$(objdump -d write | perl -nE 's/.+:\s([a-f0-9 ]+).+/$1/g and s/\s+/\\\\x/g and print')""\b\b  "

执行后会得到shellcode:

\xeb\x1a\x5e\x48\x31\xff\x48\x31\xd2\x48\x31\xc0\x66\xff\xc7\xb2\x0d\xb0\x01\x0f\x05\x48\x31\xff\xb0\x3c\x0f\x05\xe8\xe1\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21\x0a 

话说X86 的架构得自己重写代码,因为调用约定全改了。。它好好的为什么要改呢。。?


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值