➜ ~

Playing Hacks and Stuffs!


Project maintained by h4ckyou Hosted on GitHub Pages — Theme by mattgraham

PICOCTF '23

Description: This was a fun ctf i participated in with team 8h037. I really learnt a lot during this ctf thanks to the organizers for bringing such a good challenge

image

Challenge Solved

General Skills

Forensics

Reverse Engineering

WEB

Cryptography

Binary Exploitation

General Skills 8/8 :~

Chrono

image

We’re given a ssh instance to connect to after loggin i looked back at the description and saw its referring to automating task on linux image

And that means likely cron jobs

So i checked the cron jobs and got the flag image

Flag: picoCTF{Sch3DUL7NG_T45K3_L1NUX_d83baed1}

Money-Ware

image

We’re given an address which looks like a btc address and we’re asked to submit the malware name

So i just paste the address on google then saw this image

The second link looks promising then i checked it Link image

Below the news on the cyberattack shows a malware name image

Flag: picoCTF{Petya}

Permissions

image

After connecting to the ssh instance i checked what the user can run as root sudo -l image

So the user can run /usr/bin/vi as root

Checking gtfobins I got a shell escape command image

Flag: picoCTF{uS1ng_v1m_3dit0r_ad091ce1}

Repetitions

image

After downloading the enc_flag and checking its content i see that its base64 encoded image

I tried decoding it but i get another base64 encoded value image

From the challenge name repetition its likely this has been encoded multiple times

So I wrote a script to decode it until it isn’t a base64 encoded value again Solve

Running it I got the flag image

Flag: picoCTF{base64_n3st3d_dic0d!n8_d0wnl04d3d_4557ec3e}

Rule 2023

image

Checking the link provided doesn’t show the flag image

But after checking source code and using CTRL +F I got the flag image

Flag: picoCTF{h34rd_und3r5700d_4ck_cba1c711}

Useless

image

After connecting to the ssh instance i saw a file in the current directory of the user image

And its a shell script

From the challenge tag man I ran man command on the script and I got the flag image

Flag: picoCTF{us3l3ss_ch4ll3ng3_3xpl0it3d_7065}

Special

image

After connecting to the ssh server I get this weird shell image

So it capitalize the 0th index of our input making us not able to run commands

What I did next was to find any special character value that won’t be affected from the capitaliation of the 0th index of our input image

I did play around to get the value and __| worked well for me

Now we can just pass in any command we want to run

From that I got the flag image

Flag: picoCTF{5p311ch3ck_15_7h3_w0r57_b741d1b1}

Specialer

image

Just like Special Chall after loggin I got into a weird shell that doesn’t have much command image

After trying some command I got that echo works image

And we can access enumerate files using echo + a wildcard (*)

I checked the files in the user’s current working directory image

Now we can use echo and get the content of a file to the standard output stdout

Command: echo $(</etc/passwd)

Trying that I got the flag image

Flag: picoCTF{y0u_d0n7_4ppr3c1473_wh47_w3r3_d01ng_h3r3_c42168d9}

Forensics 3/6 :~

Hideme

image

First thing first I checked the file type after downloading the file given image

It’s a PNG file (image file)

On viewing it just shows the picoctf logo image

Now i check its metadata image

Running zsteg on it shows that there’s a ZIP file embedded in it image

So i’ll use binwalk to extract it image

From there I got the flag

Flag: picoCTF{Hiddinng_An_imag3_within_@n_ima9e_85e04ab8}

PcapPoisoning

image

After downloading the file attached I checked its file type which happens to be a pcap file image

Then I tried low hanging fruits by running strings on it and got the flag image

Flag: picoCTF{P64P_4N4L7S1S_SU55355FUL_4d72dfcc}

Invisible Words

image

After downloading the attached file I checked its file type and its happens to be a bmp file image

I checked the metadata of the file but I got nothing from it image

I also ran various tools to check the file but I got nothing

Then after i checked the hex dump I noticed this image

That is the file header for a zip file. You can check it out here Wikipedia

So now the idea is that we can extract the values from that spot below

But first I need to get what length it is from the zip file, and I used python for it image

So that means the zip file should start from offset 140

I wrote a script to extract the content of the zip file starting from index 140

Here’s the script Solve

After I run it, it dumps the zip file content image

Then I used binwalk to extract it’s content image

From that I got the flag

Flag: picoCTF{w0rd_d4wg_y0u_f0und_5h3113ys_m4573rp13c3_5eadc23e}

Reverse Engineering 7/9 :~

Reverse

image

After downloading the binary I checked what file it is image

And its a x64 binary which is not stripped

So i’ll run it to know what it does image

Its asking for a password to unlock the file

Since I don’t currently know it I ran strings to check for low hanging fruits

And from there I got the flag image

Flag: picoCTF{3lf_r3v3r5ing_succe55ful_d55531cd}

Safe Opener

image

After downloading the file and checking its file type i got it to be a java compiled binary image

So I used an online decompiler to decompile the .class file to a readable format

After decompiling the binary I got the flag image image image

Flag: picoCTF{SAf3_0p3n3rr_y0u_solv3d_it_b427942b}

Timer

image

After downloading the file given and checking its file type it turns out to be an apk file image

So here’s I did. First I unzip the content of the apk file then use dex2jar to convert the class file to a jar file which later i then use jd-gui to view the decompiled code image image

Flag: picoCTF{t1m3r_r3v3rs3d_succ355fully_17496}

Ready Gladiator 0

image

After checking the attached file given i couldn’t get what it does

But i just connected to the netcat instance and got the flag image

Flag: picoCTF{h3r0_t0_z3r0_4m1r1gh7_a7bf8a57}

Ready Gladiator 1/2

image

This one I didn’t even download the file but I searched for what CoreWars means then I saw this resources CoreWar Payload

And when I used the payload on the remote server it worked for both Gladiator 1 & 2

Running it for Gladiator 1 works image image

Flag: picoCTF{1mp_1n_7h3_cr055h41r5_dba6f40d}

Running it for Gladiator 2 works image image image

Flag: picoCTF{d3m0n_3xpung3r_106bc275}

No Way Out

image

We’re given the files to download and i downloaded the type for windows

After downloading and checking it out, it shows the unity files for a windows game image

When i treid playing the game initially, i noticed the player is like limited to crossing the boundry image

So after checking online for how to reverse unity file binary i got that you can edit the dll file for the game

And the particular .dll file we’re looking for should contain the program logic

It was located here image

Using dnSPY, I can manipulate it

After searching around i then moveDirection variable and edited it to a constant value image

Then on running the game again i got the flag after moving over the wall image

Flag: picoCTF{WELCOME_TO_UNITY!!}

WEB 5/7 :~

findme

image

We’re given a remote instance to connect to which is a web server and its has a login form image

Since the description says we should login as test:test1 lets try it image image

While i was login in i noticed the url had some base64 values before it gets redirected to home page

So i’ll login again but this time use burp to intercept the request image image

From here:

Right Click --> Do Intercept --> Response To Request

I got the first portion of the flag picoCTF{proxies_al image

After forwarding the request i get the second portion image

Flag: picoCTF{proxies_all_the_way_df44c94c}

MatchTheRegex

image

Same as always we’re given a remote instace which is a web server

Checking it out shows that it requires giving some text image

Since i don’t know the particular input to give it i checked the source code image

From the js portion of the script i saw the commented part of it

		// ^p.....F!?

And its a regular expression which means:

1. "^p": Matches the start of a line or string, followed by the letter "p".
2. ".....": Matches any five characters except newline.
3. "F!?": Matches the letter "F" followed by an optional exclamation mark.

So the best value to be given is picoCTF image

After submitting it I got the flag image

Other form of value can be used like pythonF, plololF as long as it matches the regrex

Flag: picoCTF{succ3ssfully_matchtheregex_08c310c6}

SOAP

image

Checking the instance given shows this image

Clicking on details and intercepting the request shows that the data which it’s trying to fetch is gotten using the xml format style image

So since its this we can perform XXE

After checking HackTricks I made the payload to read the /etc/passwd file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT data ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<data>
    <ID>&file;</ID>
</data>

On submitting that I got the flag image

Flag: picoCTF{XML_3xtern@l_3nt1t1ty_e5f02dbf}

More SQLi

image

Checking the web server instance given shows this login page image

From the challenge title which is SQLi i’ll try using sql injection to bypass the login page

Username: ' or 1=1 --
Password: ' or 1=1 --

Trying that works image

There’s another search functionality in the web app

So i’ll search for something then intercept the request with burp image

Then i will save the request in a file image

With this i can use sqlmap image

Then I dump the whole table to see if any thing is of interest there image image

Flag: picoCTF{G3tting_5QL_1nJ3c7I0N_l1k3_y0u_sh0ulD_783cc6bd} 

Java Code Analysis!?!

image

The web server source code is given

After checking it this is what i found interesting image image image

So the key is the secret key for the jwt which is 1234

I’ll connect to the web server and login using the cred user:user image image

If you try to click the flag image file it won’t allow access cause the user isn’t admin image

After i checked for the cookies i couldn’t find any JWT token image

So i decided to login again but this time pass the request through my burp proxy image image

Cool so it generated a token for me and from checking jwt.io i got its algorithm to be HS256 image

Here’s the jwt decoded value:

{
  "role": "Free",
  "iss": "bookshelf",
  "exp": 1679960313,
  "iat": 1679355513,
  "userId": 1,
  "email": "user"
}

Since we know the sign key to be 1234 that means that we can generate another token

I made a script to generate the token for me

After running it i got the new token image

So i then logged in again but this time intercept the request and replace the token to the newly generated own image image

Intercept Request --> Response To Request

Now i will replace this with the new token generated image

After forwarding the request i get logged in as admin image image image

From here we can just get the flag image

Here’s my automated script to get the flag xD Solve image image

Cryptography 4/7:~

HideToSee

image

After downloading the file attached and checking its file type shows its an image file image

It content is referring to atbash cipher and it contains the way of decoding atbash cipher

But no encrypted text is given. So now i checked if there’s any data hidden in the jpg file image

Now on viewing the encrypted data it gives this image

Cipher Text: krxlXGU{zgyzhs_xizxp_1u84w779}

We can use that table in the image already given or an online tool Dcodefr to decode it image image

Flag: picoCTF{atbash_crack_1f84d779}

ReadMyCert

image

After downloading the file attached i checked its file type and its a PEM certificate request file image

So if we view it what we will see is just the certificate file image

Next thing i did was to search how to decode .csr file with openssl

And i got this Resource

I put it in a bash script image

And after running it i got the flag image

Flag: picoCTF{read_mycert_a7163be8}

Rotation

image

We’re given the encrypted file image

So i used DcodeFR to identify the cipher type and used it also for decoding it image

Its likely a rot cipher so i used Decoder to decode it image

Flag: picoCTF{r0tat1on_d3crypt3d_25d7c61b}

SRA

image

We’re given the remote file being used

Here’s its content image

And this is what’s happening

1. It creates 16 random values which are either ascii or digits
2. After that it generates random prime numbers with 128 bits in two variables
3. It then multiplies those two variable which is stored in a new variable
4. 65537 is stored in variable sloth
5. The multiplicative inverse of sloth and (gluttony - 1) * (greed - 1) is done and stored in variable envy
6. It converts the value of pride to a long integer then does the modular exponential of pride where the public exponent is sloth and the modulus is lust

Overall this is a process of encrypting a message using RSA

So if we run the prorgam it will generate the private key (d) and its ciphertext(c)

Then it asks for our input and check if its equal to the value stored in pride. If the check is meet we get the flag else it prints out Hubris!

But now that we know both the private key and the ciphertext we can calculate:

1. kphi from ed-1
2. Then go to factordb and take every prime factor which will be put in a list
3. From there we can use any for loop with product from itertools to calculate the multplication of some factors and check the result of this multiplication which will be called n
4. Then we check if isPrime(n+1) and if (n+1).bit_lenght() = 128. If the check is meet we can save (n+1) in a list
5. With this we will get a list of all possible primes that could construct N
6. We can then make two for loops where i and j are the iterate with the list and calcualte N=i*j; if long_to_bytes(pow(c,d,N)).isprintable(): print(ong_to_bytes(pow(c,d,N)))

Thats the way I solve it

So I wrote a script for it Solve

Running it gives the flag

➜  sage solve.py
[-] Opening connection to saturn.picoctf.net on port 51615: Connected
anger = 10874849782922899596926546059091484448219162477034704964483223843381834331753
envy = 6079395884215855559684171323910149420899924737311416787335412267518949259009
vainglory?
picoCTF{7h053_51n5_4r3_n0_m0r3_3858bd66}
➜  sra 
Flag: picoCTF{7h053_51n5_4r3_n0_m0r3_3858bd66}

Binary Exploitation 7/7 :~

BabyGame01

image

I checked what file type it is and the protections enabled on the binary image

Its a x86 binary which is dynamically linked and not stripped, the protections enabled on the binary are Canary and NX (No Execute)

Next i’ll run it to get an idea of what it does image

Looks like some sort of game

Using ghidra i decompiled the binary

Here’s the main function image

This is the part am interested about

    } while (local_aac != 0x1d);
  } while (local_aa8 != 0x59);
  puts("You win!");
  if (local_aa4 != '\0') {
    puts("flage");
    win();
    fflush(stdout);

If local_aac == 0x1d and local_aa8 == 0x59 it will print out you win then another check is done that checks if the value of local_aa4 is not equal to a null terminator it will call the win() function which will give the flag image

To trigger this condition we must firstly win the game and the local variable local_aa4 must be non-zero to get the flag.

So the way to move the player of the game is by using w,a,s,d and other good functions are p,l image

And here’s what each does:

1. w --> moves the player up
2. a --> moves the player left
3. s --> moves the player right
4. d --> moves the player down
5. l --> change the player structure
6. p --> auto solve the game

And what I noticed while i tried it is that when the player goes out of bound you get a seg fault image

The reason is cause the program tried accessing a memory address that isn’t valid image

Looking at the stack layout image

  | local_aac        | [$EBP - 0xAAC]               player_x_pos (or row in map)
  | local_aa8        | [$EBP - 0xAA8]               player_x_pos (or column in map)
  | local_aa4        | [$EBP - 0xAA4]  char         flag_win_condition (!= 0)
  | local_aa0        | [$EBP - 0xAA0]  char[2700]   map_buf  

The offset between the player_x_pos and local_aa4 is 0x4

➜  game01 python3
Python 3.11.1 (main, Dec 31 2022, 10:23:59) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> hex(int(0xaa8)-int(0xaa4))
'0x4'
>>> 0x4
4
>>>

This also tells us our initial starting position is always { X, Y } = { 4, 4 }

Now the idea is that if we can reach that particular position 0x59 = 89 and also go out of bound we can overwrite the value of local_aa4 by adding extra 4 bytes since thats the required offset needed to overwrite local_aa4

The function init_player() takes the address of local_aac and writes three words, array indexing flowing into subsequent parameters of main()

local_aac[0] = 4                    = player_y_pos (or row in map)
local_aac[1] = 4   ---> local_aa8   = player_x_pos (or column in map)
local_aac[2] = 0   ---> local_aa4   = flag_win_condition (!= 0)

init_map() function confirms the purpose and ordering of the player position coordinates, as detailed above. It also exposes the exit position which is the game win condition, that is the player must reach { 29, 89 } = { 0x1d, 0x59

And the decompilation of the move_player function is

if (param_2 == 'w') {
  *param_1 = *param_1 + -1;
}
else if (param_2 == 's') {
  *param_1 = *param_1 + 1;
}
else if (param_2 == 'a') {
  param_1[1] = param_1[1] + -1;
}
else if (param_2 == 'd') {
  param_1[1] = param_1[1] + 1;
}
*(undefined *)(*param_1 * 0x5a + param_3 + param_1[1]) = player_tile;

But if we substitute with our variable names and making the code a little easier to read :

*map_buf[(player_y_pos * 0x5a) + player_x_pos)] = player_title

What we can notice there is that:

1. There is no bounds checking on position increment/decrement operations
2. These new player position values form the index of an array dereference

This is the vulnerable part of the code because we control the player position values and hence can control the dereferenced array entry (and hence address) and the character that gets written there, forming a write-what-where primitive.

So our aim here will be to underflow the map_buf array and write a non-zero value to the local_aa4 our ` if (local_aa4 != ‘\0’) {` condition , which was initialised to zero by init_player()

This means an effective position of { 0, -4 } will write the player_title character to the LSB of local_aa4

Now to solve this we need to move player position from { 4, 4 } to { 0, -4 }, this underflows the map_buf[] and writes the player’s position character over local_aa4 (satisfying the non-zero flag win condition)

Payload: aaaawwwwaaaap

So what that does is to:

1. Move left 4 times
2. Go up 4 times
3. Go out of bound with 4 bytes 
4. Auto win the game

Doing that gets me the flag locally image

So I did the same remotely image

Here’s the auto solve script Solve

Running it gives the flag image

Flag:  picoCTF{gamer_m0d3_enabled_3aa88304}

TwoSum

image

The source code is given image image

Here’s what it does:

1. Creates a function called addIntOvf and it requires 3 parameters which are result, a & b
2. What the function does is to sum up int a and int b and store them in result 
3. It then checks if the value of a and b is greater than 0 and the value of result is less than 0 
4. It then returns error
5. Also an if check is done that checks if the value of a and b is less than 0 and the result is greater than 0 
6. If its that case it returns error 
7. Else it exits

For the main function here’s what it does:

1. It prints out n1 > n1 + n2 or n2 > n1 + n2 
2. Then it prints What two positive numbers can make this possible:
3. It receives our input which are two numbers stored in &num1 and &num2
4. A variable sum is created which takes the sum of num1 and num2
5. Then it calls the addIntOvf function which takes in the sum, &num1, &num2 as parameters and check if it returns true 
6. If that returns true it prints out No overflow
7. Else if addIntOvf returns false it prints out You have an integer overflow
8. After that it then checks if the value of &num1 and &num2 are greater than 0 (non negative number)
9. If the check is meet it prints out the flag

Looking at the code what the program expects is two positive numbers that when sumed up gives a negative number

Is that possible?

Yes!!! And its called an integer overflow

So basically performing integer overflow means going above the maximum value of the signed integer, and the result usually becomes a negative number

Here’s the resource Resource

This are two integers that when added result in an integer overflow

Num1: 2147483647
Num2: 1

Giving that as the num to the binary gives an integer overflow and then the flag (locally) image

Trying that on the remote server works also image

Here’s the solve script Solve

Running it gives the flag image

Flag: picoCTF{Tw0_Sum_Integer_Bu773R_0v3rfl0w_e06700c0}

BabyGame02

image

After downloading the binary i checked its file type and the protection enabled image

Cool the only protection enabled is No-Execute

Running the binary shows the same output as the previous one image

So i decompiled it using ghidra and now here’s the difference between the it and the first binary image

After the user wins it doesn’t print any flag or calls the win function image

Since its the same function as the previous binary, i won’t share ss of the whole decompiled code

Visualising the stack frame of main() from the disassembly to show placement and relative offsets of local variables and other elemts on the stack. I’ve augmented the variables with their purpose obtained from analysis of functions (main(), init_player() and move_player())

                             **************************************************************
                             *                          FUNCTION                          *
                             **************************************************************
                             undefined main(undefined1 param_1)
             undefined         AL:1           <RETURN>
             undefined1        Stack[0x4]:1   param_1                                 XREF[1]:     08049674(*)  
             undefined4        Stack[0x0]:4   local_res0                              XREF[1]:     0804967b(R)  
             undefined1        Stack[-0x10]:1 local_10                                XREF[1]:     08049753(*)  
             undefined1        Stack[-0x11]:1 local_11                                XREF[2]:     080496eb(W), 
                                                                                                   080496ee(R)  
             undefined1        Stack[-0xa9d   local_a9d                               XREF[4]:     080496aa(*), 
                                                                                                   080496c3(*), 
                                                                                                   080496f5(*), 
                                                                                                   08049716(*)  
             undefined4        Stack[-0xaa4   local_aa4                               XREF[1]:     08049730(R)  
             undefined4        Stack[-0xaa8   local_aa8                               XREF[6]:     08049694(*), 
                                                                                                   080496a3(*), 
                                                                                                   080496bc(*), 
                                                                                                   080496fd(*), 
                                                                                                   0804970f(*), 
                                                                                                   08049725(R)  
                             main                                            XREF[5]:     Entry Point(*), 
                                                                                          _start:08049110(*), 
                                                                                          _start:08049116(*), 0804a0e8, 
                                                                                          0804a2a8(*)  
        08049674 8d 4c 24 04     LEA        ECX=>param_1,[ESP + 0x4]

move_player(player_y_pos, input_ch, map_buf) contains the same exploitable line of code that forming a write-what-where primative. We control the player X and Y position and hence the address to write to, aswell as the byte to write through the ability to change the player_title

So the vulnerable part of the code is

map_buf[(player_y_pos * 0x5a) + player_x_pos)] = player_title

This time we must overwrite a return address on the stack with the addres of the win() function to gives the flag instead of overwriting a local variable of main().

The behaviour of move_player() is slightly different in babygame02, in that before moving the player it writes to the previous player position (before move), clearing it with ‘.’ (0x2e) character before updating and writing the new player position. This means cycling this exploit to write multiple bytes is not possible as it corrupts the previous byte written with the clear. Therefore we need to find a location where only one write operation is required to divert the flow of execution to the win() function address.

After playing with the binary i noticed is that at address 0x080495b6. The value at $esp will be the return pointer image image image

What we can see there is

*EIP  0x80495b6  →  <solve_round+47> add esp, 0x10     ← $esp
It's showing that the player_move was called from the solve_round function. So our input 'p', we won't need to use the p command for game02

Now here’s what happen when i move around the map and check the stack memory address

After setting a new breakpoint at 0x8049548 = <move_player+212>: ret image image image image image

Now that @ is the player, and we’re moving it around in stack memory

And this is what happens when we go out of bound, the program will crash and its so cause the instruction pointer will try to access an invalid memory address

Now when we move round the memory it’s pointers on the stack that we’re modifying. Now the questions is… can we modify something useful to control the execution of the program so that we can get it to print the flag?

The goal is to make the eip call the win() function

But the problem is even tho we can overwrite the @ structure it only just overwrites the last byte of an address of the stack

We need something similar to the win() function address and after setting a breakpoint at *solve_round+47 image image image

Then checking the stack, i got an address of the stack that looks very similar to the win() function image

We can see the similarity between the stack address 0x08049709 and the win function address 0x0804975d

Only one byte that makes it not the same as the win function address

Now next thing is that since while we move round the map and out of bound, the player character is also moving round the stack therefore overwriting bytes on the stack which makes the program crashes, the idea is that that particular memory on the stack can be overwritten to the win function address.

And for this to occur the character needed to overwrite it is ] which will later turn to 5d in hex

➜  game02 python
Python 3.11.1 (main, Dec 31 2022, 10:23:59) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a=']'
>>> b=ord(a)
>>> hex(b)
'0x5d'
>>> 

And we know that the l function changes the player character to anything specified. So that means we can change our player character to ]

So basically, when we jump up and down, we jump in the memory. Cause 2d arrays in memory become 1d with offsets and since we know the width of the map to be 89, we know that we jump 89 bytes every time we move up and down.

We can control where this 0x5d ends up as this ] which is now the player so try and find the position on the map that is 89 bytes offset from that address that is close to the win function which is the stack address we got earlier.

So i just made a script to move round the map but out of bound i.e w

Here’s my local fuzz script Fuzz_Local

Running it locally gets me the offset image

Then i can get local flag image

python2 -c "print 'l]' + 'wwww' + 'd'*47 + 'wp'"  | ./game

But trying it remotely doesn’t work image

So its likely the stack offset i think

Then a made a brute script and auto solve script for the remote own

Here’s the Exploit

Running it works and i got the flag image image

Flag: picoCTF{gamer_jump1ng_4r0unD_498dff8d}

Hijacking

image

After i connected to the ssh remote instance i saw this file called .server.py image

Since its own by root and the aim of this chall is to get root so i decided to take a look at it image

What the script does is to attempt to gather information by pinging picoctf.org

But we don’t have any write access over this file image

So now what we can do is a python library hijack

Since those libraries i.e base64, os, socket are imported in the file we can attempted to hijack and add malicious content to those library files so that when its is being called when the .server.py is executed our malicious command will also be executed

But first we need to have write access over any of the library files

And base64.py seems ok to be abused image

So now we can add in any thing we want inside the base64.py file then after we run .server.py it will be executed

I added a command to make /bin/bash an suid binary image

Now checking sudo -l shows we can run the .server.py as root image

And that is ok cause we are trying to change the permission of a binary to suid

From here we can run the script image

We can see now that /bin/bash permission is now that of an suid binary

Root should be easy from here 👻 image

Flag: picoCTF{pYth0nn_libraryH!j@CK!n9_0083cb0b}

TicTac

image

After connecting to the ssh instance i got this two files image

Looking at the source code and the binary perm, it shows the binary is a suid binary image

And the source code for the txtreader binary is:

1. A C++ program 
2. The program checks if the user has provided exactly one command line argument (the filename to be read). If not, it displays a usage message and exits with an error code of 1
3. The program opens the file using an input file stream (std::ifstream).
4. The program uses the stat() system call to retrieve the file's status information, which includes the owner's user ID. If stat() returns an error (-1), the program displays an error message and exits with an error code of 1.
5. The program compares the owner's user ID to the ID of the current user (obtained using getuid()). If they don't match, the program displays an error message and exits with an error code of 1.
6. The program reads the contents of the file line by line using std::getline() and outputs each line to the console using std::cout.
7. If the file cannot be opened, the program displays an error message and exits with an error code of 1.
8. If everything goes well, the program exits with a success code of 0.

Overall, this program reads a file and outputs its contents to the console, but only if the user has permission to read the file (i.e., if they are the owner)

At this point what we would love to read is the flag.txt file image

But the problem now is the file is only own by root

So since the program reads files owned by the user, we won’t be able to read the flag.txt

Thats what its normally supposed to do but here’s the vulnerability

From the task description it says toc-tou which means Race Condition image

After reading some of the articles i found a way to exploit this

And its using symlink

Here’s the exploitation phase: image

touch fake_flag
while true; do ln -sf flag.txt link; ln -sf fake_flag link; done &
while true; do ./txtreader link 2>/dev/null; done > val &
cat val

From that we can get the flag

Flag: picoCTF{ToctoU_!s_3a5y_5748402c}

VNE

image

After i connected to the ssh instance i saw a binary there and ran it

But i got this image

So it reqires the SECRET_DIR environment to be set

It can be easily set like this image

So from the output we can tell that the binary does directory listing on the path specified

Now what we can try here is command injection in the environment variable

Doing that works image

Flag: picoCTF{Power_t0_man!pul4t3_3nv_fc3ff2c9}

Thats all 👻

Teammate Writeup

Forensics

Cryptography

Reverse Engineering

Here’s the link to the writeup Link