mirror of
http://git.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/nihilist/hacking-blogposts.git
synced 2025-05-16 04:16:59 +00:00
219 lines
6.9 KiB
Markdown
219 lines
6.9 KiB
Markdown
# h3 time
|
||
|
||
## Downloading the binary file
|
||
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/h3_time/time
|
||
--2021-03-07 12:51:05-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/h3_time/time
|
||
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
|
||
Resolving github.com (github.com)... 140.82.121.3
|
||
Connecting to github.com (github.com)|140.82.121.3|:443... connected.
|
||
HTTP request sent, awaiting response... 302 Found
|
||
Location: https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/h3_time/time [following]
|
||
--2021-03-07 12:51:05-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/h3_time/time
|
||
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.110.133, ...
|
||
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.
|
||
HTTP request sent, awaiting response... 200 OK
|
||
Length: 8864 (8.7K) [application/octet-stream]
|
||
Saving to: ‘time’
|
||
|
||
time 100%[================================================================>] 8.66K --.-KB/s in 0.006s
|
||
|
||
2021-03-07 12:51:06 (1.41 MB/s) - ‘time’ saved [8864/8864]
|
||
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ file time
|
||
time: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=4972fe3e2914c74bc97f0623f0c4643c40300dab, not stripped
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ chmod +x time
|
||
|
||
|
||
|
||
` ![]()
|
||
|
||
## Solution
|
||
|
||
First let's take a look at the binary with pwn checksec as well as running it:
|
||
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ pwn checksec time; ./time
|
||
[*] '/home/nothing/binexp/3/time/time'
|
||
Arch: amd64-64-little
|
||
RELRO: Partial RELRO
|
||
Stack: Canary found
|
||
NX: NX enabled
|
||
PIE: No PIE (0x400000)
|
||
Welcome to the number guessing game!
|
||
I'm thinking of a number. Can you guess it?
|
||
Guess right and you get a flag!
|
||
Enter your number: 1234
|
||
Your guess was 1234.
|
||
Looking for 34981616.
|
||
Sorry. Try again, wrong guess!
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ ./time
|
||
Welcome to the number guessing game!
|
||
I'm thinking of a number. Can you guess it?
|
||
Guess right and you get a flag!
|
||
Enter your number: 4321
|
||
Your guess was 4321.
|
||
Looking for 994945792.
|
||
Sorry. Try again, wrong guess!
|
||
|
||
|
||
|
||
|
||
So here we see that we have a 64bit binary. When we run it, it prompts us to guess a number. Let's check what ghidra finds on that binary:
|
||
|
||
|
||
undefined8 main(void)
|
||
|
||
{
|
||
time_t tVar1;
|
||
long in_FS_OFFSET;
|
||
uint local_18;
|
||
uint local_14;
|
||
long local_10;
|
||
|
||
local_10 = *(long *)(in_FS_OFFSET + 0x28);
|
||
tVar1 = time((time_t *)0x0);
|
||
srand((uint)tVar1);
|
||
local_14 = rand();
|
||
puts("Welcome to the number guessing game!");
|
||
puts("I\'m thinking of a number. Can you guess it?");
|
||
puts("Guess right and you get a flag!");
|
||
printf("Enter your number: ");
|
||
fflush(stdout);
|
||
__isoc99_scanf(&DAT;_00400bbc,&local;_18);
|
||
printf("Your guess was %u.\n",(ulong)local_18);
|
||
printf("Looking for %u.\n",(ulong)local_14);
|
||
fflush(stdout);
|
||
if (local_14 == local_18) {
|
||
puts("You won. Guess was right! Here\'s your flag:");
|
||
giveFlag();
|
||
}
|
||
else {
|
||
puts("Sorry. Try again, wrong guess!");
|
||
}
|
||
fflush(stdout);
|
||
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
|
||
/* WARNING: Subroutine does not return */
|
||
__stack_chk_fail();
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
Here we see something interesting, first of all the **rand** function which should give a random number, as well as the scanf call with the %u format string stored in local_18. Basically the main function creates a random number, then prompts us for some number to store into local_18, and then it checks if the 2 numbers are the same. If they are we enter the giveFlag function:
|
||
|
||
|
||
void giveFlag(void)
|
||
|
||
{
|
||
FILE *__stream;
|
||
long in_FS_OFFSET;
|
||
char local_118 [264];
|
||
long local_10;
|
||
|
||
local_10 = *(long *)(in_FS_OFFSET + 0x28);
|
||
memset(local_118,0,0x100);
|
||
__stream = fopen("/home/h3/flag.txt","r");
|
||
if (__stream == (FILE *)0x0) {
|
||
puts("Flag file not found! Contact an H3 admin for assistance.");
|
||
}
|
||
else {
|
||
fgets(local_118,0x100,__stream);
|
||
fclose(__stream);
|
||
puts(local_118);
|
||
}
|
||
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
|
||
/* WARNING: Subroutine does not return */
|
||
__stack_chk_fail();
|
||
}
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
Here we see that this function reads and prints out the flag file from **/home/h3/flag.txt** What we need to figure out is what the output of the **rand** function will be. Thing is, the output of the ran dunction is not actually random. The output is based off a value called a 'seed' which it uses to determine what number sequence to generate. SO if we can get the same seed, we can get **rand** to generate the same sequence of numbers. Looking at the decompiled code, we see the following:
|
||
|
||
|
||
tVar1 = time((time_t *)0x0);
|
||
srand((uint)tVar1);
|
||
|
||
|
||
|
||
Here we see tVar1 gets the current time as a seed, therefore we can write a C program that uses the current time as a seed, and output a digit and redirect the output to the target:
|
||
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ vim exploit.c
|
||
|
||
|
||
|
||
|
||
#include<****stdio.h>
|
||
#include <****time.h>
|
||
#include <****stdlib.h>
|
||
#include <****stdint.h>
|
||
#include <****string.h>
|
||
|
||
int main()
|
||
{
|
||
uint32_t rand_num;
|
||
srand(time(0)); //seed with current time
|
||
rand_num = rand();
|
||
uint32_t ans;
|
||
printf("%d\n", rand_num);
|
||
}
|
||
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ gcc exploit.c -o exploit
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ ./exploit
|
||
1779237112
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ ./exploit
|
||
1476399991
|
||
|
||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/time]
|
||
→ ./exploit | ./time
|
||
Welcome to the number guessing game!
|
||
I'm thinking of a number. Can you guess it?
|
||
Guess right and you get a flag!
|
||
Enter your number: Your guess was 1333337650.
|
||
Looking for 1333337650.
|
||
You won. Guess was right! Here's your flag:
|
||
${g0tt3m_boyz}
|
||
|
||
|
||
|
||
And that's it ! We managed to print the flag.
|
||
|
||
## Title
|
||
|
||
text
|
||
|
||
|
||
|
||
|
||
` ![]()
|
||
|
||
## Title
|
||
|
||
text
|
||
|
||
|
||
|
||
|
||
` ![]()
|
||
|