Challenge: Link
Phần 1: Đọc mã và suy luận:
Đầu tiên, chương trình bắt nhập 1 string và kiểm tra độ dài của string đó tại dòng: CMP DWORD PTR SS:[LOCAL.38], 15
Ta có thể suy ra là chuỗi cần nhập sẽ có độ dài bằng 15h nghĩa là 21 ký tự, ta có thể tiến hành thử nhập chuỗi có độ dài bằng 21 ký tự và nhỏ hơn 21 ký tự để kiếm chứng
Bắt đầu từ đây trở xuống là thuật toán kiểm tra dữ liệu input bằng 1 vòng lặp để so sánh 2 string. Nếu khác nhau thì hiện ra string "Try again!" và chương trình kết thúc còn đúng thì tiếp tục kiểm tra cho đến cuối string. 2 strinh giống nhau hoàn toàn thì trả về chuỗi "G00d j0b!!!"Thuật toán ta có thể được viết lại như sau:
#include <stdio.h>
#include <string.h>
int main()
{
char flag[80];
strcpy(flag,"SVATTT_fib0nacii_xxxx");
char input[80];
gets(input);
if (strlen(input)==21)
{
for(int i=0;i<21;i++)
{
if (input[i]!=flag[i])
{
printf("Wrong!!!");
return 0;
}
}
printf("Good jobs!!!");
}
return 0;
}
Bước 2, mình sẽ lấy flag thật
Để lấy flag, mình cần tìm chỗ kiểm tra compare ký tự và lệnh nhảy
Lệnh compare 2 ký tự của string và lệnh nhảy là 2 dòng:
CMP ESI,EDX // so sánh 2 ký tự trong string
JE SHORT 010F1153 // Nhảy đến địa chỉ 010F1153 nếu "bằng"
Để chương trình không kiểm tra 2 string, ta sửa lệnh JE SHORT 010F1153 thành JMP SHORT 010F1153
Sau đó ta đặt BreakPoint tại dòng CMP ESI,EDX hoặc dòng JMP SHORT 010F1153 để lấy nội dung của thanh ghi EDX. Các ký tự nhận được là flag thật.
Ký tự đầu tiên mang giá trị 53h là ký tự S trong bảng ASCII
Tiếp tục chương trình ta sẽ lấy được các ký tự tiếp theo
Ở bài này mình sẽ không đưa ra flag mà để các bạn tự làm
Không có nhận xét nào:
Đăng nhận xét