实验吧-加减乘除

实验吧-加减乘除

题目描述

http://ctf5.shiyanbar.com/overflow/1/

一段简单的汇编代码;实现的功能是:删除当前目录下指定文件名的文件。题目的目的是将这段代码转化为hex格式,输入获取KEY,然后提交即可。

.global _start
_start:
        jmp     test1
test2:
        pop     %ebx
        movb    $0xa,%al
        int     $0x80
        movb    $0x1, %al
        xor     %ebx, %ebx
        int     $0x80
test1:
        call    test2
        .string "delfile"
学习过程
运行

首先我测试了这段代码的可用性以及它的具体功能:在linux下编写这段代码,并编译为x86格式;在当前路径下命名一个文件;运行。

本人是在linux-x86-64平台上编写,解决的第一个问题是如何在64bit-linux运行32bit汇编程序。

  • 在x64编译运行64bit汇编代码
nasm -f elf64 shell.asm -o shell.o
ld shell.o -o shell
./shell

其中,shell.asm是x64汇编代码

  • 在x64编译运行32bit汇编代码
as sumer.s -o sumer.o --32
ld -m elf_i386 -o sumer sumer.o

其中sumer.s是32bit汇编代码;as表示linux上的汇编器是assembler;—32表示32bit。ld链接;m参数是让ld模仿后面跟的链接器,也就是elf_i386格式的链接器。

运行成功。

转化为shellcode

接下来尝试将汇编转换为hex格式的shellcode.

bin2shell

网上找到的一个bin2shell函数,可以将二进制的shell程序转为x86_64的shellcode.

原理:objdump -d后取带数字的每行的第二个字段 并在其前加入 “\x“ 之后echo输出。

#!/bin/bash
for i in $(objdump -d $1 |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo
#execve
objdump -d binary-file

于是本人将上边已经运行成功的ELF文件放在这里进行objdump操作。生成了“\x…”串,提交,错误。

猜测原因:这个objdump并没有把这个二进制文件以x86平台的格式进行处理??还可能潜入了一些x86-64的内容??

可以尝试:在x86平台上在进行测试!!!!

有点忘记还经历过哪些尝试了…….最后还是见别人的write-up了。

汇编学习

在转换的过程中我也想过先理解清楚这段汇编的内容,并且也曾怀疑过是否会有漏洞…..然后构造新的shellcode拿到shell权限…….想偏了,但是汇编的学习如下:

int x80调用

下图是int x80的调用表;

int80

将表与汇编结合,可以看到test2的前三行是将”delfile”参数传给ebp(从表中给可以看到ebp中存储的数据类型是const char*,于是我个人这么猜测……);然后将al赋值为10;接着调用sys_unlink(就是实现了删除文件的功能)。

pop     %ebx
movb    $0xa,%al
int     $0x80

test2的后三行将ebp置0;eax置1;调用int x80之后就是执行了exit(0)

movb    $0x1, %al
xor     %ebx, %ebx
int     $0x80

学习这段汇编时的几个疑惑点是:

  • call test2之后运行test2;但是按照顺序执行的话,test2运行结束之后会不会继续运行test1,陷入死循环……后来看了别人的一个对汇编程序运行过程的详解发现并不会,因为程序在调用call的时候,已经将next_address(也就是ret_address)放在栈中,调用结束之后继续执行返回地址的内容。

    汇编语言入门教程

  • call test2后边的’ .string “delfile” ‘什么时候被程序加载。查询一些资料之后,看到有些.string其实是属于data段的,但是有些程序是在全局定义的,而这里是在函数内部定义的,因此我猜测这里的.string是test1函数的传入参数??所以汇编写在这个位置???

    注意汇编程序由三个不同的元素组成:
    
    指示(Directives) 以点号开始,用来指示对编译器,连接器,调试器有用的结构信息。指示本身不是汇编指令。例如,.file 只是记录原始源文件名。.data表示数据段(section)的开始地址, 而 .text 表示实际程序代码的起始。.string 表示数据段中的字符串常量。 .globl main指明标签main是一个可以在其它模块的代码中被访问的全局符号 。至于其它的指示你可以忽略。
    标签(Labels) 以冒号结尾,用来把标签名和标签出现的位置关联起来。例如,标签.LC0:表示紧接着的字符串的名称是 .LC0. 标签main:表示指令 pushq %rbp是main函数的第一个指令。按照惯例, 以点号开始的标签都是编译器生成的临时局部标签,其它标签则是用户可见的函数和全局变量名称。
    指令(Instructions) 实际的汇编代码 (pushq %rbp), 一般都会缩进,以便和指示及标签区分开来。
  • ebp的值在运行过程中可以被传入参数吗?不是用来标志某一个函数栈桢的栈顶么??

exploit

直接使用pwntools

from pwn import *
code = """.global _start
_start:
        jmp     test1
test2:
        pop     ebx
        mov     al, 0xa
        int     0x80
        mov     al, 0x1
        xor     ebx, ebx
        int     0x80
test1:
        call    test2
        .string "delfile" """

context(arch='x86', os='linux', endian='little', word_size=32)
shellcode = asm(code).encode('hex')
re = ''
while len(shellcode):
    re += r'\x'+shellcode[:2]
    shellcode = shellcode[2:]
print re

先写成C代码,gcc编译,然后objdump生成

找到对应的汇编代码,将code拼起来(00之前的code)即可:\xeb\x0b\x5b\xb0\x0a\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xf0\xff\xff\xff\x64\x65\x6c\x66\x69\x6c\x65

还没有解决的问题…

1.为什么只能要\x00之前的内容?

2.汇编传参过程?

技能GET
x86汇编&&x64汇编
x64汇编 x86汇编
体系都是Intel的X8086体系,X64指的是64位的CPU,X86则指32位的CPU(原则上也包括16位的)
x64汇编转shellcode
for i in $(objdump -d scode | grep "^ " |cut -f2); do echo -n '\x'$i; done;
mov
MOVB moves a byte, MOVW moves a word, MOVL moves a long, MOVQ moves a quad-word
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值