تحدي Zelda and the Zombies عبارة عن لعبة مطلوب أن تقتل أي أحد من الأعداء عشان يطلع الفلاق، لكن طاقتهم كبيرة جداً 999999 وصعب تقتلهم يدوي، قلت أجرب استخدم Cheat Engine عشان أدور على طاقة واحد منهم وأنقصتها مباشرة في الذاكرة ومن ضربة واحدة يموت
تحدي 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 يأخذ 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 يعطيك السيرفر صور عشوائية كثيرة، ويطلب تحديد مكان البنت في كل مرة ولازم تجاوبها كلها صح، لاحظت أن البنت تتغير كثير، بس الحيوانات شبه ثابتين، كتبت سكربت عشان أشيلهم باستخدام OpenCV وتركته يجاوب على تحديات السيرفر إلى أن طلع الـ flag
السكربت الحل: https://gist.github.com/Barakat/4e5d34407cc6fc5e3619e371e6a81e0d
تحدي 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