Challenge Name
Problem
Exploit the function pointers in this program. It is also found in /problems/pointy_4_3b3533bd4e08119669feda53e8cb0502 on the shell server. Source.
Solution
The provided program allows us to enter students and professors. Students can then rate the professors.
The bug in the program is that we can select professors as students and students as professors. We can write the
lastScoreof aProfessorand then treat it as aStudentto control thescoreProfessorfield.The
StudentandProfessorstructs are as follows:struct Professor { char name[NAME_SIZE]; int lastScore; }; struct Student { char name[NAME_SIZE]; void (*scoreProfessor)(struct Professor*, int); };scoreProfessoris a function pointer that is in the same position relative to thestructaslastScoreis inProfessor. We can create aProfessorand set thelastScorevariable to the address ofwin(). Then, we can convert that professor to a student, which will override thescoreProfessorpointer and point it to thewin()function. (scoreProfessoris pointed togiveScoreToProfessor()on line 79:student->scoreProfessor=&giveScoreToProfessor;.) Thus, when thescoreProfessorpointer is called (close to the end of the file:student->scoreProfessor(professor, value);), thewin()function will be executed and we will get the flag.Script (script.py) Walkthrough:
Allocate a student
s1Allocate a professor
p1Use student
s1to give the scoreGive the score to professor
p1Set the
lastScoreattribute of professorp1to the address ofwin()The loop in vuln.c restarts
Allocate another student
s2(only necessary to proceed to next inputs in program)Allocate another professor
p2(only necessary to proceed to next inputs in program)Use professor
p1(which has the address ofwin()) to give a score. This converts professorp1to a student, thus overwriting thescoreProfessorfunction pointer towin().Give the score to professor
p1. This does not matter since we only care about the last line (student->scoreProfessor(professor, value);) wherescoreProfessor(akawin()) is called. You could usep2here as well since it is the extra professor we created earlier.Give a score of
0to professorp1, but not really since thescoreProfessorfunction pointer points towin()and notgiveScoreToProfessor()since we changed it by converting aProfessorto aStudent.
Run the script.py
python script.py USER=<username> PASSWORD=<password>:[*] '/home/<username>/Documents/PicoCTF/Binary Exploitation/pointy/vuln' Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8048000) [+] Connecting to 2019shell1.picoctf.com on port 22: Done [*] <username>@2019shell1.picoctf.com: Distro Ubuntu 18.04 OS: linux Arch: amd64 Version: 4.15.0 ASLR: Enabled [+] Opening new channel: 'pwd': Done [+] Receiving all data: Done (14B) [*] Closed SSH channel with 2019shell1.picoctf.com [*] Working directory: '/tmp/tmp.klHpIRVO8i' [+] Opening new channel: 'ln -s /home/<username>/* .': Done [+] Receiving all data: Done (0B) [*] Closed SSH channel with 2019shell1.picoctf.com [*] win address: 0x8048696 [+] Starting remote process b'/problems/pointy_4_3b3533bd4e08119669feda53e8cb0502/vuln' on 2019shell1.picoctf.com: pid 1203280 [+] picoCTF{g1v1ng_d1R3Ct10n5_c7465fbf}
Flag
picoCTF{g1v1ng_d1R3Ct10n5_c7465fbf}
Last updated
Was this helpful?