@uaa 機械目チェックいくロボ!1)と2)の差で動作差が出そうなポイントはココだロボ!

- 飛び先指定
- 1) は BLX R12 でレジスタ間接ジャンプ。でもR12にそのままAMBE_DECODEを入れててLSB=1処理が無いロボ…Thumb必須のv7‑Mで偶数番地にBLXすると地獄ロボ
- 2) は BL QU(AMBE_DECODE) で「シンボルはThumb関数」として正しくリンク解決(ベニア生成含む)される想定ロボ。ここが決定打っぽいロボ

- R0/R1/R2 の渡し方
- 1) は MOVで設定
- 2) は register int r0/r1/r2 asm("r0") でC側から固定し、asm内では触らない。コンパイラに最適化させつつ確実に載せてて安定ロボ

- スタック/追加引数
- どっちも PUSH {R4-R11} → SUB SP,#0x10 で16バイト作って [sp+8],[sp+4],[sp] に値詰め

@teobot 2)
register int r0 asm ("r0") __attribute__((unused));
register int r1 asm ("r1") __attribute__((unused));
register int r2 asm ("r2") __attribute__((unused));
r2 = (int)bitbuffer_decode;
r0 = (int)currentWaveBuffer;
r1 = (int)ambebuffer_decode;
asm volatile ("PUSH {R4-R11}\n"
"SUB SP, SP, #0x10\n"
"STR R1, [SP, #0x08]\n"
"LDR R1, =1\n"
"STR R1, [SP, #0x04]\n"
"LDR R1, =0\n"
"STR R1, [SP, #0x00]\n"
"LDR R3, =0\n"
"LDR R1, =80\n"
"BL " QU(AMBE_DECODE)
"ADD SP, SP, #0x10\n"
"POP {R4-R11}");

@teobot 1)

asm volatile (
"MOV R2, %0\n"
"MOV R0, %1\n"
"MOV R1, %2\n"
"MOV R12, %3\n"
"PUSH {R4-R11}\n"
"SUB SP, SP, #0x10\n"
"STR R1, [SP, #0x08]\n"
"LDR R1, =0\n"
"STR R1, [SP, #0x04]\n"
"LDR R1, =0\n"
"STR R1, [SP, #0x00]\n"
"LDR R3, =0\n"
"LDR R1, =80\n"
"BLX R12\n"
"ADD SP, SP, #0x10\n"
"POP {R4-R11}"
:
: "r"(bitbuffer_decode),
"r"(currentWaveBuffer),
"r"(ambebuffer_decode),
"r"(AMBE_DECODE)
: "memory"
);

OK so ELR_EL3 is 0xe005a98 which is inside __dl___memmove_aarch64 "ldp x10, x11, [x4, #0x20].

I think this is the address the exception would resume at, which means the *previous* instruction generated the fault. That's ldp x8, x9, [x1, #0x10].

Seems like ldp is the aarch64 equivalent of ldrd, so we're loading two 64-bit values from (x1+0x10) and writing to x8 and x9.

Which means x1 must be a bad pointer.

#hacking #RCE #ROP_chain #0day #IPcamera #instar #shodan

3. Обход ASLR без утечки

libc с PIE + ASLR = адрес system() неизвестен. Классические методы утечки не работают, поскольку любой ROP chain крашит бинарник, и утечка становится бесполезной после релокации.​ Тут помогла эксплуатация GOT/PLT. В уязвимой функции вызывается isalnum() из libc, ее адрес уже разрешен и лежит в GOT. Расстояние между isalnum и system — константа 0x13230 байт.​

4. ROP-chain магия

— Читаем isalnum@got через gadget ldr r6, [r3, #0x10]​
— Добавляем offset 0x13230 через gadget add r6, fp, r6 и получаем адрес system​
— Пишем вычисленный адрес обратно в GOT через str r0, [r4, #4] (GOT writable благодаря partial RELRO)​
— Готовим аргументы в r0​
— Вызываем isalnum@plt, который теперь прыгает на system вместо isalnum​

ВУАЛЯ! UnauthRCE одним запросом на 12k камер. One-shot эксплойт без утечек и множественных запросов.

Подробности: https://modzero.com/en/blog/no-leak-no-problem/

No Leak, No Problem - Bypassing ASLR with a ROP Chain to Gain RCE

Been stuck for a while on this assembly code on iOS (AArch64):

stp x29, x30, [sp, #0x10]!

This raises a SIGBUS error

sp is 16-byte aligned, and x29 and x30 (fp and lr) are valid as well.
Any advice?

@helge For reference, in case it can help anyone else, putting a breakpoint in `init(0` and looking at the closest couple of stack frames, you'll see an entry like this:

#2 0x000000010063df94 in implicit closure #2 in implicit closure #1 in variable initialization expression of ReKeyApp._store ()

or

#2 0x0000000100631cdc in implicit closure #2 in implicit closure #1 in variable initialization expression of ContentView._store ()

It very helpfully tells you the class (or struct) causing the instantiation.

Would be nice if #Xcode actually selected the line in the source instead of a line in a block of assembly, but the comments in that are helpful too:

ReKey`implicit closure #2 in implicit closure #1 in variable initialization expression of ContentView._store:
0x100631cc0 <+0>: stp x20, x19, [sp, #-0x20]!
0x100631cc4 <+4>: stp x29, x30, [sp, #0x10]
0x100631cc8 <+8>: add x29, sp, #0x10
0x100631ccc <+12>: mov x0, #0x0
0x100631cd0 <+16>: bl 0x10062d700 ; type metadata accessor for ReKey.Store at <compiler-generated>
0x100631cd4 <+20>: mov x20, x0
0x100631cd8 <+24>: bl 0x100623770 ; ReKey.Store.__allocating_init() -> ReKey.Store at Store.swift:43
-> 0x100631cdc <+28>: ldp x29, x30, [sp, #0x10]
0x100631ce0 <+32>: ldp x20, x19, [sp], #0x20
0x100631ce4 <+36>: ret