Skip to content

Instantly share code, notes, and snippets.

@Barakat
Last active April 14, 2020 17:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Barakat/5abcaf64bc38aa513bbeee382dc43105 to your computer and use it in GitHub Desktop.
Save Barakat/5abcaf64bc38aa513bbeee382dc43105 to your computer and use it in GitHub Desktop.
Nullcon 2020 writeup

Zelda and the Zombies

تحدي Zelda and the Zombies عبارة عن لعبة مطلوب أن تقتل أي أحد من الأعداء عشان يطلع الفلاق، لكن طاقتهم كبيرة جداً 999999 وصعب تقتلهم يدوي، قلت أجرب استخدم Cheat Engine عشان أدور على طاقة واحد منهم وأنقصتها مباشرة في الذاكرة ومن ضربة واحدة يموت

zelda


returminator

تحدي returminator فيه برنامج Python ينفذ برنامج ثاني (ELF executable) أكثر من مرة، وفي كل مرة يعطيه input مختلف من ملف اسمه blob:

o = [296, 272, 272, 272, 296, 360, 272, 424, 272, 208, 120, 120, 120, 96, 120, 120, 120, 120, 120, 120, 120, 208, 120, 120, 208, 208, 208, 208, 208, 272, 120, 208, 208]
r = [208, 225, 237, 20, 214, 183, 79, 105, 207, 217, 125, 66, 123, 104, 97, 99, 107 , 105, 109, 50, 48, 202, 111, 111, 29, 63, 223, 36, 0, 124, 100, 219, 32]

cmd = ['./main']
rets = []

with open('blob', 'rb') as f:
    i = 0
    for offset in o:
        data = f.read(offset)
        open(f'i{i}.bin', 'wb').write(data)
        i += 1
        continue
        p = subprocess.Popen(cmd, stdin=subprocess.PIPE)
        p.stdin.write(data)
        p.communicate()
        rets.append(p.returncode)

برنامج الـ ELF يقرأ ملف اسمه flag ويقرأ الـ input الي أعطاه إياه برنامج الـ Python ثم يصير overflow، لما يصير الـ overflow يتنفذ برنامج ثالث عبارة عن rop gadgets كان مخزن في الـ input، هذي الـ ROPs تجري عمليات مختلفة على الـ flag ثم تحط نتيجة العمليات في الـ exit status.

61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
61 61 61 61 61 61 61 61 A2 11 40 00 00 00 00 00
A0 40 40 00 00 00 00 00 9A 11 40 00 00 00 00 00
00 00 00 00 00 00 00 00 A4 11 40 00 00 00 00 00
EA 11 40 00 00 00 00 00 D6 11 40 00 00 00 00 00
A2 11 40 00 00 00 00 00 A0 40 40 00 00 00 00 00
9C 11 40 00 00 00 00 00 02 00 00 00 00 00 00 00
A8 11 40 00 00 00 00 00 EE 11 40 00 00 00 00 00
DB 11 40 00 00 00 00 00 A2 11 40 00 00 00 00 00
A0 40 40 00 00 00 00 00 9E 11 40 00 00 00 00 00
04 00 00 00 00 00 00 00 AC 11 40 00 00 00 00 00
F2 11 40 00 00 00 00 00 E0 11 40 00 00 00 00 00
BD 11 40 00 00 00 00 00 A4 11 40 00 00 00 00 00
A8 11 40 00 00 00 00 00 AC 11 40 00 00 00 00 00
9A 11 40 00 00 00 00 00 64 00 00 00 00 00 00 00
C1 11 40 00 00 00 00 00 EA 11 40 00 00 00 00 00
FF 11 40 00 00 00 00 00 61

كتبت disassembler للـ ROPs وحللتها يدوي، طلع نظام معادلات خطية استخدمت z3 لحله

...
pop    rax = flag
pop    rdi = 25
add    rax, rdi
mov    rdi, rax
movzx  rdi, BYTE PTR [rdi]

pop    rax = flag
pop    rsi = 26
add    rax, rsi
mov    rsi, rax
movzx  rsi, BYTE PTR [rsi]

xor    rax, rax
add    rax, rdi
add    rax, rsi
mov    rdi, rax
call   0x4010a0 <exit@plt>
; rdi = 217
;
; =====================
pop    rax = flag
pop    rdi = 30
add    rax, rdi
mov    rdi, rax
movzx  rdi, BYTE PTR [rdi]

call   0x4010a0 <exit@plt>
; rdi = 125
;
...
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char flag; // [rsp+0h] [rbp-30h]
  FILE *fp; // [rsp+28h] [rbp-8h]

  puts("Hello world!");
  fp = fopen("flag", "r");
  if ( !fp )
    exit(1);
  fgets(&flag, 35, fp);
  fclose(fp);
  memset(dest, 0, 35uLL);
  strcpy(dest, &flag);
  read(0, &flag, 1024uLL);
  return 0LL;
}

سكربت الحل: https://gist.github.com/Barakat/c78ed4fb143596c88b9c900aeb007ef3#file-rop_disasm-py


meek boi

تحدي meek boi يأخذ shellcode وينفذه، لكن يمنعه من أن يطبع أو يقرأ شيء من stdout أو stderr:

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  __int16 v3; // ax
  __int16 v4; // ax
  __pid_t v5; // [rsp+24h] [rbp-3Ch]
  ssize_t v6; // [rsp+38h] [rbp-28h]

  v3 = getpagesize();
  v6 = (ssize_t)mmap(0LL, ~(v3 - 1) & 0x4000, 7, 34, -1, 0LL); // حجز ذاكرة للشل كود
  if ( !v6 )
    __assert_fail("psc != NULL", "chall.c", 0x5Cu, "int main(int, char **)");
  fflush(stdout);
  v4 = getpagesize();
  *(_BYTE *)(v6 + (signed int)read(0, (void *)v6, ~(v4 - 1) & 0x4000)) = 0xC3u;
  v5 = fork();
  if ( v5 < 0 )
    perror("fork");
  if ( v5 > 0 )
  {
    wait(0LL);
    exit(0);
  }
  child_do((void (__fastcall *)(_QWORD, signed __int64))v6); // تنفيذ شل كود في child process
}

void __fastcall __noreturn child_do(void (__fastcall *a1)(_QWORD, signed __int64))
{
  unsigned int fd; // ST24_4

  fclose(stdin);
  fclose(stdout);
  fclose(stderr);
  fd = open("/dev/null", 2);
  dup2(fd, 0);
  dup2(fd, 1);
  dup2(fd, 2);
  a1(fd, 2LL); // تنفيذ الشل كود المدخل
  exit(0);
}

أخذت shellcode يسوي reverse TCP connection من exploit-db عشان يوجه الـ I/O للـ socket، وعدلته عشان يصل بسيرفري وأخذت شل على السيرفر وطلعت الفلاق.


dora

تحدي dora يعطيك السيرفر صور عشوائية كثيرة، ويطلب تحديد مكان البنت في كل مرة ولازم تجاوبها كلها صح، لاحظت أن البنت تتغير كثير، بس الحيوانات شبه ثابتين، كتبت سكربت عشان أشيلهم باستخدام OpenCV وتركته يجاوب على تحديات السيرفر إلى أن طلع الـ flag

before after

السكربت الحل: https://gist.github.com/Barakat/4e5d34407cc6fc5e3619e371e6a81e0d


year3000

تحدي year3000 فيه 3000 برنامج Linux، ويسألك السيرفر عن مدخل عينه عشوائية يختارها بحيث يخلي البرنامج الي اختاره يطبع Well done، ولازم تجاوب بسرعة، حللت عينه منها، لقيت بعضها x86 وبعضها x64 وتتشابه كثير، حددت الاختلافات وكتبت سكربت يجاوب.

_BOOL8 __fastcall main(__int64 a1, char **a2, char **a3)
{
...
  v4 = sub_80A(&s);
  if ( v4 )
    puts("Well done");
  else
    puts("You have failed");
  return v4 != 1;
}

__int64 __fastcall sub_80A(char *a)
{
  unsigned int v2; // [rsp+14h] [rbp-Ch]
  signed int i; // [rsp+18h] [rbp-8h]

  v2 = 1;
  for ( i = 0; i < 77; ++i ) // 77 يختلف
  {
    if ( 'w' != a[i] ) // 'w' يختلف
    {
      v2 = 0;
      break;
    }
  }
  if ( memcmp(a + 77, &unk_201010, 8uLL) ) // unk_201010 بيانات بحجم 8 بايت تختلف
    v2 = 0;
  return v2;
}

سكربت الحل: https://gist.github.com/Barakat/95d88833635859bd004c629d23c19678

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment