mirror of
http://git.nowherejezfoltodf4jiyl6r56jnzintap5vyjlia7fkirfsnfizflqd.onion/nihilist/hacking-blogposts.git
synced 2025-05-16 04:16:59 +00:00
add hacking blogposts as they are
This commit is contained in:
parent
fa65088be1
commit
325b9c3814
1904 changed files with 91353 additions and 0 deletions
84
3/0.md
Normal file
84
3/0.md
Normal file
|
@ -0,0 +1,84 @@
|
|||
# Binary Exploitation
|
||||
|
||||
## Downloading the binary file
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
||||
## Solution
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
![]()
|
||||
|
||||
## Title
|
||||
|
||||
text
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
||||
## Title
|
||||
|
||||
text
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
BIN
3/0.png
Normal file
BIN
3/0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 75 KiB |
BIN
3/1.png
Normal file
BIN
3/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 108 KiB |
BIN
3/2.png
Normal file
BIN
3/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
219
3/h3.md
Normal file
219
3/h3.md
Normal file
|
@ -0,0 +1,219 @@
|
|||
# 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
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
301
3/prep.md
Normal file
301
3/prep.md
Normal file
|
@ -0,0 +1,301 @@
|
|||
# Sunshine CTF 2017 Prepared
|
||||
|
||||
## Downloading the binary file
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/sunshinectf17_prepared/prepared
|
||||
--2021-03-07 13:57:41-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/sunshinectf17_prepared/prepared
|
||||
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/sunshinectf17_prepared/prepared [following]
|
||||
--2021-03-07 13:57:41-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/sunshinectf17_prepared/prepared
|
||||
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.111.133, ...
|
||||
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
|
||||
HTTP request sent, awaiting response... 200 OK
|
||||
Length: 12888 (13K) [application/octet-stream]
|
||||
Saving to: ‘prepared’
|
||||
|
||||
prepared 100%[================================================================>] 12.59K --.-KB/s in 0.001s
|
||||
|
||||
2021-03-07 13:57:42 (16.2 MB/s) - ‘prepared’ saved [12888/12888]
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ file prepared
|
||||
prepared: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=9cd9483ed0e7707d3addd2de44da60d2575652fb, not stripped
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ chmod +x prepared
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
||||
## Solution
|
||||
|
||||
So let's first run pwn checksec on the binary before executing it to see what it does:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ pwn checksec prepared
|
||||
[*] '/home/nothing/binexp/3/prep/prepared'
|
||||
Arch: amd64-64-little
|
||||
RELRO: Full RELRO
|
||||
Stack: Canary found
|
||||
NX: NX enabled
|
||||
PIE: PIE enabled
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ ./prepared
|
||||
0 days without an incident.
|
||||
123
|
||||
Well that didn't take long.
|
||||
You should have used 63.
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ ./prepared
|
||||
0 days without an incident.
|
||||
63
|
||||
Well that didn't take long.
|
||||
You should have used 67.
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ ./prepared
|
||||
0 days without an incident.
|
||||
67
|
||||
Well that didn't take long.
|
||||
You should have used 24.
|
||||
|
||||
|
||||
|
||||
Here we see that this is a 64 bit binary with everything enabled (full relro, canary, nx and pie). It prompts us for input to make us guess a random number, let's take a look at it in ghidra:
|
||||
|
||||

|
||||
|
||||
And here we get the following code for the main function:
|
||||
|
||||
|
||||
undefined8 main(void)
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
time_t tVar2;
|
||||
FILE *__stream;
|
||||
char *pcVar3;
|
||||
long in_FS_OFFSET;
|
||||
uint local_464;
|
||||
char local_448 [64];
|
||||
char local_408 [512];
|
||||
char local_208 [504];
|
||||
long local_10;
|
||||
|
||||
local_10 = *(long *)(in_FS_OFFSET + 0x28);
|
||||
tVar2 = time((time_t *)0x0);
|
||||
srand((uint)tVar2);
|
||||
local_464 = 0;
|
||||
while ((int)local_464 < 0x32) {
|
||||
iVar1 = rand();
|
||||
printf("%d days without an incident.\n",(ulong)local_464);
|
||||
sprintf(local_208,"%d",(ulong)(uint)(iVar1 % 100));
|
||||
__isoc99_scanf(" %10s",local_408);
|
||||
strtok(local_408,"\n");
|
||||
iVar1 = strcmp(local_208,local_408);
|
||||
if (iVar1 != 0) {
|
||||
puts("Well that didn\'t take long.");
|
||||
printf("You should have used %s.\n",local_208);
|
||||
/* WARNING: Subroutine does not return */
|
||||
exit(0);
|
||||
}
|
||||
local_464 = local_464 + 1;
|
||||
}
|
||||
puts("How very unpredictable. Level Cleared");
|
||||
__stream = fopen("flag.txt","r");
|
||||
while( true ) {
|
||||
pcVar3 = fgets(local_448,0x32,__stream);
|
||||
if (pcVar3 == (char *)0x0) break;
|
||||
printf("%s",local_448);
|
||||
}
|
||||
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
|
||||
/* WARNING: Subroutine does not return */
|
||||
__stack_chk_fail();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Just like in the previous 2 challenges, time is declared as a seed with the srand function, and then it uses **rand** to generate values that are modded by 100 (value%100), and we have to guess it in a loop 50 times, So in order to guess the rand number 50 times in a row, this is based off of the seed, and since the seed is simply the current time, we can write a simple C program to get the seed and generate the numbers it expects:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ vim exploit.c
|
||||
|
||||
|
||||
|
||||
|
||||
****#include <****stdio.h>
|
||||
#include <****stdlib.h>
|
||||
#include <****time.h>
|
||||
#include <****string.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i, out;
|
||||
time_t var0 = time(NULL);
|
||||
srand(var0);
|
||||
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
out = rand() % 100;
|
||||
printf("%d\n", out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Here we compile it with gcc:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ gcc exploit.c -o exploit
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ ./exploit
|
||||
83
|
||||
93
|
||||
92
|
||||
55
|
||||
70
|
||||
63
|
||||
4
|
||||
64
|
||||
54
|
||||
21
|
||||
87
|
||||
42
|
||||
77
|
||||
17
|
||||
74
|
||||
86
|
||||
57
|
||||
18
|
||||
72
|
||||
7
|
||||
52
|
||||
76
|
||||
46
|
||||
78
|
||||
81
|
||||
83
|
||||
19
|
||||
55
|
||||
20
|
||||
14
|
||||
21
|
||||
55
|
||||
59
|
||||
13
|
||||
10
|
||||
81
|
||||
76
|
||||
67
|
||||
46
|
||||
83
|
||||
88
|
||||
33
|
||||
77
|
||||
17
|
||||
2
|
||||
3
|
||||
4
|
||||
59
|
||||
21
|
||||
28
|
||||
|
||||
|
||||
|
||||
Now let's pipe it into the stdin of our binary:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/prep]
|
||||
→ ./exploit | ./prepared
|
||||
0 days without an incident.
|
||||
1 days without an incident.
|
||||
2 days without an incident.
|
||||
3 days without an incident.
|
||||
4 days without an incident.
|
||||
5 days without an incident.
|
||||
6 days without an incident.
|
||||
7 days without an incident.
|
||||
8 days without an incident.
|
||||
9 days without an incident.
|
||||
10 days without an incident.
|
||||
11 days without an incident.
|
||||
12 days without an incident.
|
||||
13 days without an incident.
|
||||
14 days without an incident.
|
||||
15 days without an incident.
|
||||
16 days without an incident.
|
||||
17 days without an incident.
|
||||
18 days without an incident.
|
||||
19 days without an incident.
|
||||
20 days without an incident.
|
||||
21 days without an incident.
|
||||
22 days without an incident.
|
||||
23 days without an incident.
|
||||
24 days without an incident.
|
||||
25 days without an incident.
|
||||
26 days without an incident.
|
||||
27 days without an incident.
|
||||
28 days without an incident.
|
||||
29 days without an incident.
|
||||
30 days without an incident.
|
||||
31 days without an incident.
|
||||
32 days without an incident.
|
||||
33 days without an incident.
|
||||
34 days without an incident.
|
||||
35 days without an incident.
|
||||
36 days without an incident.
|
||||
37 days without an incident.
|
||||
38 days without an incident.
|
||||
39 days without an incident.
|
||||
40 days without an incident.
|
||||
41 days without an incident.
|
||||
42 days without an incident.
|
||||
43 days without an incident.
|
||||
44 days without an incident.
|
||||
45 days without an incident.
|
||||
46 days without an incident.
|
||||
47 days without an incident.
|
||||
48 days without an incident.
|
||||
49 days without an incident.
|
||||
How very unpredictable. Level Cleared
|
||||
[1] 2904178 done ./exploit |
|
||||
2904179 segmentation fault (core dumped) ./prepared
|
||||
|
||||
|
||||
|
||||
And that's it! we have been able to guess the random number 50 times.
|
||||
|
||||
## Title
|
||||
|
||||
text
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
||||
## Title
|
||||
|
||||
text
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
278
3/tux.md
Normal file
278
3/tux.md
Normal file
|
@ -0,0 +1,278 @@
|
|||
# hsctf 2019 tux talk show
|
||||
|
||||
## Downloading the binary file
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ wget https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow
|
||||
|
||||
--2021-03-07 13:24:34-- https://github.com/guyinatuxedo/nightmare/raw/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow
|
||||
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/hsctf19_tuxtalkshow/tuxtalkshow [following]
|
||||
--2021-03-07 13:24:35-- https://raw.githubusercontent.com/guyinatuxedo/nightmare/master/modules/09-bad_seed/hsctf19_tuxtalkshow/tuxtalkshow
|
||||
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.108.133, ...
|
||||
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.
|
||||
HTTP request sent, awaiting response... 200 OK
|
||||
Length: 21112 (21K) [application/octet-stream]
|
||||
Saving to: ‘tuxtalkshow’
|
||||
|
||||
tuxtalkshow 100%[================================================================>] 20.62K --.-KB/s in 0.003s
|
||||
|
||||
2021-03-07 13:24:35 (5.81 MB/s) - ‘tuxtalkshow’ saved [21112/21112]
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ file tuxtalkshow
|
||||
tuxtalkshow: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=8c0d2b94392e01fecb4b54999cc8afe6fa99653d, for GNU/Linux 3.2.0, not stripped
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ chmod +x tuxtalkshow
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
||||
## Solution
|
||||
|
||||
First let's run pwn checksec on the binary file before executing it to see what it does:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ pwn checksec tuxtalkshow
|
||||
[*] '/home/nothing/binexp/3/tux/tuxtalkshow'
|
||||
Arch: amd64-64-little
|
||||
RELRO: Partial RELRO
|
||||
Stack: Canary found
|
||||
NX: NX enabled
|
||||
PIE: PIE enabled
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ ./tuxtalkshow
|
||||
Welcome to Tux Talk Show 2019!!!
|
||||
Enter your lucky number: 13371337
|
||||
|
||||
|
||||
|
||||
So here we have a 64bit binary with PIE enabled. When we run it it prompts us for a number. So let's check it out from inside of ghidra:
|
||||
|
||||

|
||||
|
||||
And here we get a gigantic main function:
|
||||
|
||||
|
||||
undefined8 main(void)
|
||||
|
||||
{
|
||||
int iVar1;
|
||||
time_t tVar2;
|
||||
basic_ostream *pbVar3;
|
||||
long in_FS_OFFSET;
|
||||
int local_290;
|
||||
int local_28c;
|
||||
int local_288;
|
||||
int local_284;
|
||||
undefined4 local_280;
|
||||
undefined4 local_27c;
|
||||
undefined4 local_278;
|
||||
undefined4 local_274;
|
||||
undefined4 local_270;
|
||||
undefined4 local_26c;
|
||||
int local_268 [8];
|
||||
basic_string local_248 [32];
|
||||
basic_istream local_228 [520];
|
||||
long local_20;
|
||||
|
||||
local_20 = *(long *)(in_FS_OFFSET + 0x28);
|
||||
std::basic_ifstream>::basic_ifstream((char *)local_228,0x1020b0);
|
||||
tVar2 = time((time_t *)0x0);
|
||||
srand((uint)tVar2);
|
||||
/* try { // try from 0010127e to 001012c0 has its CatchHandler @ 00101493 */
|
||||
pbVar3 = std::operator<<((basic_ostream *)std::cout,"Welcome to Tux Talk Show 2019!!!");
|
||||
std::basic_ostream>::operator<<
|
||||
((basic_ostream> *)pbVar3,
|
||||
std::endl>);
|
||||
std::operator<<((basic_ostream *)std::cout,"Enter your lucky number: ");
|
||||
std::basic_istream>::operator>>
|
||||
((basic_istream> *)std::cin,&local;_290);
|
||||
local_280 = 0x79;
|
||||
local_27c = 0x12c97f;
|
||||
local_278 = 0x135f0f8;
|
||||
local_274 = 0x74acbc6;
|
||||
local_270 = 0x56c614e;
|
||||
local_26c = 0xffffffe2;
|
||||
local_268[0] = 0x79;
|
||||
local_268[1] = 0x12c97f;
|
||||
local_268[2] = 0x135f0f8;
|
||||
local_268[3] = 0x74acbc6;
|
||||
local_268[4] = 0x56c614e;
|
||||
local_268[5] = 0xffffffe2;
|
||||
local_28c = 0;
|
||||
while (local_28c < 6) {
|
||||
iVar1 = rand();
|
||||
local_268[local_28c] = local_268[local_28c] - (iVar1 % 10 + -1);
|
||||
local_28c = local_28c + 1;
|
||||
}
|
||||
local_288 = 0;
|
||||
local_284 = 0;
|
||||
while (local_284 < 6) {
|
||||
local_288 = local_288 + local_268[local_284];
|
||||
local_284 = local_284 + 1;
|
||||
}
|
||||
if (local_288 == local_290) {
|
||||
std::__cxx11::basic_string,std::allocator>::basic_string();
|
||||
/* try { // try from 00101419 to 00101448 has its CatchHandler @ 0010147f */
|
||||
std::operator>>(local_228,local_248);
|
||||
pbVar3 = std::operator<<((basic_ostream *)std::cout,local_248);
|
||||
std::basic_ostream>::operator<<
|
||||
((basic_ostream> *)pbVar3,
|
||||
std::endl>);
|
||||
std::__cxx11::basic_string,std::allocator>::~basic_string
|
||||
((basic_string,std::allocator> *)local_248);
|
||||
}
|
||||
std::basic_ifstream>::~basic_ifstream
|
||||
((basic_ifstream> *)local_228);
|
||||
if (local_20 != *(long *)(in_FS_OFFSET + 0x28)) {
|
||||
/* WARNING: Subroutine does not return */
|
||||
__stack_chk_fail();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Here we cansee that it starts off by scanning the contents of flag.txt and saves it into **local_228**. Then it initialized an integer array with size entries, although the decompilation only shows 4. So let's look at the assembly code:
|
||||
|
||||
|
||||
001012bc e8 8f fd CALL operator>> undefined operator>>(basic_istre
|
||||
ff ff
|
||||
} // end try from 0010127e to 001012c0
|
||||
001012c1 c7 85 88 MOV dword ptr [RBP + local_280],0x79
|
||||
fd ff ff
|
||||
79 00 00 00
|
||||
001012cb c7 85 8c MOV dword ptr [RBP + local_27c],0x12c97f
|
||||
fd ff ff
|
||||
7f c9 12 00
|
||||
001012d5 c7 85 90 MOV dword ptr [RBP + local_278],0x135f0f8
|
||||
fd ff ff
|
||||
f8 f0 35 01
|
||||
001012df c7 85 94 MOV dword ptr [RBP + local_274],0x74acbc6
|
||||
fd ff ff
|
||||
c6 cb 4a 07
|
||||
001012e9 c7 85 98 MOV dword ptr [RBP + local_270],0x56c614e
|
||||
fd ff ff
|
||||
4e 61 6c 05
|
||||
001012f3 c7 85 9c MOV dword ptr [RBP + local_26c],0xffffffe2
|
||||
fd ff ff
|
||||
e2 ff ff ff
|
||||
|
||||
|
||||
|
||||
We also see that it uses time as a seed. It performs an algorithm where it will generate random numbers by using time a sa seed to edit the values of array, and then it accumulate all of those values to end up with the number we are supposed to guess. Since the rand function is directly based off of the seed, and since the seed is the time, we know what the values the rand function will output, and thus end up with the following C program:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ vim exploit.c
|
||||
|
||||
|
||||
|
||||
|
||||
****#include <****stdio.h>
|
||||
#include <****stdlib.h>
|
||||
#include <****stdint.h>
|
||||
#include <****time.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int array[6];
|
||||
int i, output;
|
||||
uint32_t randVal, ans;
|
||||
|
||||
srand(time(0));
|
||||
|
||||
|
||||
i = 0;
|
||||
|
||||
array[0] = 0x79;
|
||||
array[1] = 0x12c97f;
|
||||
array[2] = 0x135f0f8;
|
||||
array[3] = 0x74acbc6;
|
||||
array[4] = 0x56c614e;
|
||||
array[5] = 0xffffffe2;
|
||||
|
||||
while (i < 6)
|
||||
{
|
||||
randVal = rand();
|
||||
array[i] = array[i] - ((randVal % 10) - 1);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
output = 0;
|
||||
|
||||
while (i < 6)
|
||||
{
|
||||
output = output + array[i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
|
||||
printf("%d\n", output);
|
||||
}
|
||||
|
||||
|
||||
Then we compile our C code:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ gcc exploit.c -o exploit
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ ./exploit
|
||||
|
||||
|
||||
|
||||
let's try it on the binary file:
|
||||
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ ./exploit
|
||||
234874834
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ ./exploit
|
||||
234874839
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ ./exploit
|
||||
234874828
|
||||
|
||||
[ 192.168.0.18/24 ] [ /dev/pts/25 ] [binexp/3/tux]
|
||||
→ ./exploit | ./tuxtalkshow
|
||||
Welcome to Tux Talk Show 2019!!!
|
||||
Enter your lucky number: flag{g0tt3m_boyz}
|
||||
|
||||
|
||||
|
||||
And that's it ! We have been able to print out the flag.
|
||||
|
||||
## Title
|
||||
|
||||
text
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
||||
## Title
|
||||
|
||||
text
|
||||
|
||||
|
||||
|
||||
|
||||
` ![]()
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue