radareorg / radare2

UNIX-like reverse engineering framework and command-line toolset
https://www.radare.org/
GNU Lesser General Public License v3.0
20.53k stars 2.99k forks source link

How does radare allow us to find the offset of a given value in De Bruijn pattern? #14830

Closed yangboyd closed 6 months ago

yangboyd commented 5 years ago

Follow this https://www.megabeets.net/a-journey-into-radare-2-part-2/ But I got below: r2 -r profile.rr2 -d megabeets_0x2 Process with PID 2630 started... = attach 2630 2630 bin.baddr 0x00400000 Using 0x400000 asm.bits 64 -- Temporally drop the verbosity prefixing the commands with ':' [0x7f86726d11e0]> dc

.:: Megabeets ::.

Show me what you got: child stopped with signal 11 [+] SIGNAL 11 errno=0 addr=0x00000000 code=128 ret=0

Any way to find the offset?

Maijin commented 5 years ago

Hello @yangboyd

The article says:

"Did you notice that now our prompt points to 0x41417641? This is an invalid address which represents ‘AvAA’ (asciim little-endian), a fragment from our pattern. radare allows us to find the offset of a given value in De Bruijn pattern."

Did you check the prompt [XXX]> given by radare2 (missing from your paste)

yangboyd commented 5 years ago

But It is the address of the "ret", not the chars padded.

r2 -r profile.rr2 -d megabeets_0x2 Process with PID 2630 started... = attach 2630 2630 bin.baddr 0x00400000 Using 0x400000 asm.bits 64 -- Temporally drop the verbosity prefixing the commands with ':' [0x7f86726d11e0]> dc

.:: Megabeets ::.

Show me what you got: child stopped with signal 11 [+] SIGNAL 11 errno=0 addr=0x00000000 code=128 ret=0 [0x00400800]>

┌ (fcn) sym.beet 113
│ sym.beet (int32_t arg1);
│ ; var int32_t var_98h @ rbp-0x98
│ ; var int32_t var_90h @ rbp-0x90
│ ; var int32_t var_88h @ rbp-0x88
│ ; var int32_t var_80h @ rbp-0x80
│ ; arg int32_t arg1 @ rdi
│ ; CALL XREF from main (0x400841)
│ 0x00400790 55 push rbp
│ 0x00400791 4889e5 mov rbp, rsp
│ 0x00400794 4881eca00000. sub rsp, 0xa0
│ 0x0040079b 4889bd68ffff. mov qword [var_98h], rdi ; arg1
│ 0x004007a2 488b9568ffff. mov rdx, qword [var_98h]
│ 0x004007a9 488d4580 lea rax, qword [var_80h]
│ 0x004007ad 4889d6 mov rsi, rdx
│ 0x004007b0 4889c7 mov rdi, rax
│ 0x004007b3 e818fdffff call sym.imp.strcpy ;[1] ; char strcpy(char dest, const char src)
│ 0x004007b8 48b84d656761. movabs rax, 0x746565626167654d ; 'Megabeet'
│ 0x004007c2 48898570ffff. mov qword [var_90h], rax
│ 0x004007c9 66c78578ffff. mov word [var_88h], 0x73 ; 's' ; 115
│ 0x004007d2 488d8570ffff. lea rax, qword [var_90h]
│ 0x004007d9 4889c7 mov rdi, rax
│ 0x004007dc e83cfeffff call sym.rot13 ;[2]
│ 0x004007e1 488d9570ffff. lea rdx, qword [var_90h]
│ 0x004007e8 488d4580 lea rax, qword [var_80h]
│ 0x004007ec 4889d6 mov rsi, rdx
│ 0x004007ef 4889c7 mov rdi, rax
│ 0x004007f2 e809fdffff call sym.imp.strcmp ;[3] ; int strcmp(const char
s1, const char *s2)
│ 0x004007f7 85c0 test eax, eax
│ 0x004007f9 0f94c0 sete al
│ 0x004007fc 0fb6c0 movzx eax, al
│ 0x004007ff c9 leave
│ ;-- rip:
└ 0x00400800 c3 ret

ITAYC0HEN commented 5 years ago

Hey :) Did you compile the file yourself? Did you disable ASLR?

yangboyd commented 5 years ago

Hey :) Did you compile the file yourself? Did you disable ASLR?

Yes, disabled ASLR: cat /proc/sys/kernel/randomize_va_space 0

gcc -fno-stack-protector -z execstack -o megabeets_0x2 megabeets_0x2.c

rabin2 -I megabeets_0x2 arch x86 baddr 0x400000 binsz 6723 bintype elf bits 64 canary false class ELF64 compiler GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-11)/GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36) crypto false endian little havecode true intrp /lib64/ld-linux-x86-64.so.2 laddr 0x0 lang c linenum true lsyms true machine AMD x86-64 architecture maxopsz 16 minopsz 1 nx false os linux pcalign 0 pic false relocs true relro partial rpath NONE sanitiz false static false stripped false subsys linux va true

trufae commented 6 months ago

i think the answer was quite misleading and totally not helpful at all, also the ticket is quite old, but didnt went trhough until now

you need to fill the buffer with the deburjn pattern you can use r2 or ragg2 for this:

ragg2 -P 120
4141414241414341414441414541414641414741414841414941414a41414b41414c41414d41414e41414f41415041415141415241415341415441415541415641415741415841415941415a41416141416241416341416441416541416641416741416841416941416a41416b41416c41416d41416e4141

so when you get the crash you can use drr to see where the register points to and the initial bytes of that pattern and then use this command to find out the offset inside the buffer that modifies the register in question:

[0x00000000]> wopO 0x41416e41
116
[0x00000000]>

and from the shell:

0$ ragg2 -q 0x41416e41
Little endian: 116
Big endian: 115
0$

note that the value passed to -q is expected to be in a numeric form, because that's how its usually stored in registers. so it's using cfg.bigendian to compute the raw value in memory and give you the offset inside the initial buffer.

This should be documented in the book if it isnt already