# [Write up for debugging refresher crash course](https://pwn.college/fundamentals/debugging-refresher) ## Level 1 Đầu tiên khi vào trong challenge thì nó mở lên gdb vì thế mình bấm lệnh `run` và chương trình bị dùng lại do có một breakpoint ở trong hàm main vì thế mình gõ lệnh `c` để continue để bỏ qua breakpoint và thế là mình có flag ![image](https://hackmd.io/_uploads/SkuuObnaa.png) ``` Flag: pwn.college{kK4JdhtMfhAlFRkTG6n6dgFJKsk.0FN0IDLzgTN1QzW} ``` ## Level 2 Chạy thử chương trình thì ta có thể thấy được như sau hệ thống cho phép chúng ta nhập vào đó một số ngẫu nhiên và so sánh với kết quả của hệ thống đúng thì ra flag không thì đoán lại ![image](https://hackmd.io/_uploads/SkXjlhnpT.png) Ta thử sử dụng lệnh `info register` rồi sau đó để xem các giá trị thanh ghi thì thấy một thứ khá là hay ho đấy chính là việc thanh ghi `r12` chứa giá trị ngẫu nhiên để có thể có được flag ![image](https://hackmd.io/_uploads/r11Pb3hpT.png) ![image](https://hackmd.io/_uploads/S1TdZnnTT.png) Vậy thì lấy giá trị của r12 rồi get flag thôi ![image](https://hackmd.io/_uploads/Bk_Ab3nTa.png) ``` Flag: pwn.college{sHNnKrx35NLkzahnHYIe4QVgASA.0VN0IDLzgTN1QzW} ``` ## Level 3 Gần như tương tự với level 2 thì bây giờ ta phải đọc được giá trị ngẫu nhiên ở trong stack mình đã sử dụng câu lệnh `x/16gx $rsp` để đọc được các giá trị ở trong stack thì ta có thể thấy được như sau ![image](https://hackmd.io/_uploads/HyZ2_tppT.png) Cột đầu tiên là địa chỉ cột thứ hai là offset của mảng và cuối cùng là giá trị mà mảng đó lưu giá trị ta cần tìm nằm ở dòng thứ 3 copy rồi get flag thôi ![image](https://hackmd.io/_uploads/Hy4dhYppT.png) ``` Flag: pwn.college{ETxo7Bwap8kHQF94oYZXJxWoMnW.0lN0IDLzgTN1QzW} ``` ## Level 4 Ở trong level này chúng ta sử dụng câu lệnh `x/16gx $rbp-0x18` để có thể đọc được giá trị ngẫu nhiên và đặt breakpoint ở phần scanf để có thể xem được giá trị của `rbp` ```= (gdb) x/16gx $rbp 0x7fffad6b4ea0: 0x0000000000000000 0x00007f287cd15083 0x7fffad6b4eb0: 0x00007f287cf1d620 0x00007fffad6b4f98 0x7fffad6b4ec0: 0x0000000100000000 0x000056021ecbeaa6 0x7fffad6b4ed0: 0x000056021ecbed60 0x218d2e0aacedbfae 0x7fffad6b4ee0: 0x000056021ecbe2a0 0x00007fffad6b4f90 0x7fffad6b4ef0: 0x0000000000000000 0x0000000000000000 0x7fffad6b4f00: 0xde7274dc318dbfae 0xdfddd7a80c83bfae 0x7fffad6b4f10: 0x0000000000000000 0x0000000000000000 (gdb) x/16gx $rbp-0x18 0x7fffad6b4e88: 0x54fe8055fcfee10a 0x00007fffad6b4f90 0x7fffad6b4e98: 0x19f5ed5952e0a100 0x0000000000000000 0x7fffad6b4ea8: 0x00007f287cd15083 0x00007f287cf1d620 0x7fffad6b4eb8: 0x00007fffad6b4f98 0x0000000100000000 0x7fffad6b4ec8: 0x000056021ecbeaa6 0x000056021ecbed60 0x7fffad6b4ed8: 0x218d2e0aacedbfae 0x000056021ecbe2a0 0x7fffad6b4ee8: 0x00007fffad6b4f90 0x0000000000000000 0x7fffad6b4ef8: 0x0000000000000000 0xde7274dc318dbfae (gdb) c Continuing. 123 You input: 123 The correct answer is: 54fe8055fcfee10a [Inferior 1 (process 3994) exited with code 01] (gdb) ``` Điền 4 lần là ta có được flag thôi ```= (gdb) x/16gx $rbp-0x18 0x7ffc1647bfd8: 0x0d191147011ccb24 0x8bde2fe14369f791 0x7ffc1647bfe8: 0xfe428058bbea4a00 0x0000000000000000 0x7ffc1647bff8: 0x00007fcb1a53d083 0x00007fcb1a745620 0x7ffc1647c008: 0x00007ffc1647c0e8 0x0000000100000000 0x7ffc1647c018: 0x0000563096b0eaa6 0x0000563096b0ed60 0x7ffc1647c028: 0x40b45074f3b20e69 0x0000563096b0e2a0 0x7ffc1647c038: 0x00007ffc1647c0e0 0x0000000000000000 0x7ffc1647c048: 0x0000000000000000 0xbf4c7cfb73b20e69 (gdb) c Continuing. 0d191147011ccb24 You input: d191147011ccb24 The correct answer is: d191147011ccb24 You win! Here is your flag: pwn.college{sGvc4kdK-I0Jnj3hkTN4B0p33Sz.01N0IDLzgTN1QzW} [Inferior 1 (process 9502) exited normally] ``` ## Level 5 Cách làm giống hệt như là level 4 nhưng lần này là gần 10 lần điền số ```= Flag: pwn.college{c6iUQo9EvyIJu3UQTE1_KY3W_sW.0FO0IDLzgTN1QzW} ``` ## Level 6 Lần này là tới tận 64 lần điền số nên mình đã viết một script nhỏ để tự động hóa cái việc điền số đoạn mã script như sau ```= from pwn import * import binascii p = process("/challenge/embryogdb_level6") p.recvuntil(b"(gdb) ") p.sendline(b"run") p.recvuntil(b"(gdb) ") p.sendline(b"b *main+625") p.recvuntil(b"(gdb) ") p.sendline(b"c") for i in range(63): p.recvuntil(b"(gdb) ") p.sendline(b"x/16gx $rbp-0x18") output = str(p.recvline()) print(output) output1 = str(output[1:]) output2 = output1.split("\\t") print("Run " + str(i)) print(output2[1]) p.recvuntil(b"(gdb) ") p.sendline(b"c") p.recvuntil(b"Continuing.\n") p.sendline(str(output2[1]).encode()) p.interactive() ``` Ở lần cuối thì mình điền thủ công bằng tay và thế là ta có được flag ## Level 7 Ở phần mô tả cũng đã nói rất rõ các làm của bài này như nào rồi ``` GDB is a very powerful dynamic analysis tool which you can use in order to understand the state of a program throughout its execution. You will become familiar with some of gdb's capabilities in this module. As we demonstrated in the previous level, gdb has FULL control over the target process. Under normal circumstances, gdb running as your regular user cannot attach to a privileged process. This is why gdb isn't a massive security issue which would allow you to just immediately solve all the levels. Nevertheless, gdb is still an extremely powerful tool. Running within this elevated instance of gdb gives you elevated control over the entire system. To clearly demonstrate this, see what happens when you run the command `call (void)win()`. As it turns out, all of the levels in this module can be solved in this way. GDB is very powerful! ``` Chỉ việc chạy câu lệnh `call (void)win()` là ta có được flag thôi ```= Flag: pwn.college{8ci4zgcLAAJ2K-SYTtfTMIb85z_.0FM1IDLzgTN1QzW} ``` ## Level 8 Ở phần này thì nó lắt léo hơn chút nếu như ta chạy cái câu lệnh kia thì không chạy được nhưng khi ta phân tích cái mã assembly của hàm `win()` thì ta có thể thấy được như sau ```= 0x0000564afe32d951 <+0>: endbr64 0x0000564afe32d955 <+4>: push %rbp 0x0000564afe32d956 <+5>: mov %rsp,%rbp 0x0000564afe32d959 <+8>: sub $0x10,%rsp 0x0000564afe32d95d <+12>: movq $0x0,-0x8(%rbp) 0x0000564afe32d965 <+20>: mov -0x8(%rbp),%rax 0x0000564afe32d969 <+24>: mov (%rax),%eax 0x0000564afe32d96b <+26>: lea 0x1(%rax),%edx 0x0000564afe32d96e <+29>: mov -0x8(%rbp),%rax 0x0000564afe32d972 <+33>: mov %edx,(%rax) 0x0000564afe32d974 <+35>: lea 0x73e(%rip),%rdi # 0x564afe32e0b9 0x0000564afe32d97b <+42>: callq 0x564afe32d180 <puts@plt> 0x0000564afe32d980 <+47>: mov $0x0,%esi 0x0000564afe32d985 <+52>: lea 0x749(%rip),%rdi # 0x564afe32e0d5 0x0000564afe32d98c <+59>: mov $0x0,%eax 0x0000564afe32d991 <+64>: callq 0x564afe32d240 <open@plt> 0x0000564afe32d996 <+69>: mov %eax,0x26a4(%rip) # 0x564afe330040 <flag_fd.5712> 0x0000564afe32d99c <+75>: mov 0x269e(%rip),%eax # 0x564afe330040 <flag_fd.5712> 0x0000564afe32d9a2 <+81>: test %eax,%eax 0x0000564afe32d9a4 <+83>: jns 0x564afe32d9ef <win+158> 0x0000564afe32d9a6 <+85>: callq 0x564afe32d170 <__errno_location@plt> 0x0000564afe32d9ab <+90>: mov (%rax),%eax 0x0000564afe32d9ad <+92>: mov %eax,%edi 0x0000564afe32d9af <+94>: callq 0x564afe32d270 <strerror@plt> 0x0000564afe32d9b4 <+99>: mov %rax,%rsi 0x0000564afe32d9b7 <+102>: lea 0x722(%rip),%rdi # 0x564afe32e0e0 0x0000564afe32d9be <+109>: mov $0x0,%eax 0x0000564afe32d9c3 <+114>: callq 0x564afe32d1c0 <printf@plt> 0x0000564afe32d9c8 <+119>: callq 0x564afe32d1f0 <geteuid@plt> 0x0000564afe32d9cd <+124>: test %eax,%eax 0x0000564afe32d9cf <+126>: je 0x564afe32da66 <win+277> 0x0000564afe32d9d5 <+132>: lea 0x734(%rip),%rdi # 0x564afe32e110 0x0000564afe32d9dc <+139>: callq 0x564afe32d180 <puts@plt> 0x0000564afe32d9e1 <+144>: lea 0x750(%rip),%rdi # 0x564afe32e138 0x0000564afe32d9e8 <+151>: callq 0x564afe32d180 <puts@plt> 0x0000564afe32d9ed <+156>: jmp 0x564afe32da66 <win+277> 0x0000564afe32d9ef <+158>: mov 0x264b(%rip),%eax # 0x564afe330040 <flag_fd.5712> 0x0000564afe32d9f5 <+164>: mov $0x100,%edx --Type <RET> for more, q to quit, c to continue without paging-- 0x0000564afe32d9fa <+169>: lea 0x265f(%rip),%rsi # 0x564afe330060 <flag.5711> 0x0000564afe32da01 <+176>: mov %eax,%edi 0x0000564afe32da03 <+178>: callq 0x564afe32d200 <read@plt> 0x0000564afe32da08 <+183>: mov %eax,0x2752(%rip) # 0x564afe330160 <flag_length.5713> 0x0000564afe32da0e <+189>: mov 0x274c(%rip),%eax # 0x564afe330160 <flag_length.5713> 0x0000564afe32da14 <+195>: test %eax,%eax 0x0000564afe32da16 <+197>: jg 0x564afe32da3c <win+235> 0x0000564afe32da18 <+199>: callq 0x564afe32d170 <__errno_location@plt> 0x0000564afe32da1d <+204>: mov (%rax),%eax 0x0000564afe32da1f <+206>: mov %eax,%edi 0x0000564afe32da21 <+208>: callq 0x564afe32d270 <strerror@plt> 0x0000564afe32da26 <+213>: mov %rax,%rsi 0x0000564afe32da29 <+216>: lea 0x760(%rip),%rdi # 0x564afe32e190 0x0000564afe32da30 <+223>: mov $0x0,%eax 0x0000564afe32da35 <+228>: callq 0x564afe32d1c0 <printf@plt> 0x0000564afe32da3a <+233>: jmp 0x564afe32da67 <win+278> 0x0000564afe32da3c <+235>: mov 0x271e(%rip),%eax # 0x564afe330160 <flag_length.5713> 0x0000564afe32da42 <+241>: cltq 0x0000564afe32da44 <+243>: mov %rax,%rdx 0x0000564afe32da47 <+246>: lea 0x2612(%rip),%rsi # 0x564afe330060 <flag.5711> 0x0000564afe32da4e <+253>: mov $0x1,%edi 0x0000564afe32da53 <+258>: callq 0x564afe32d1a0 <write@plt> 0x0000564afe32da58 <+263>: lea 0x75b(%rip),%rdi # 0x564afe32e1ba 0x0000564afe32da5f <+270>: callq 0x564afe32d180 <puts@plt> 0x0000564afe32da64 <+275>: jmp 0x564afe32da67 <win+278> 0x0000564afe32da66 <+277>: nop 0x0000564afe32da67 <+278>: leaveq 0x0000564afe32da68 <+279>: retq ``` Ta đặt thanh ghi `rip` ở `win+47` để bắt đầu việc in ra flag bằng việc dùng câu lệnh sau `set $rip=win+47` sau đó ta chạy lệnh `c` để in ra được flag ```= Flag: pwn.college{MsfbIgm9sIqkWqV9DjF_mUK6tCp.dlzMzMDLzgTN1QzW} ```