__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
unsigned int v3; // eax
size_t v4; // rax
int i; // [rsp+1Ch] [rbp-A4h]
int j; // [rsp+20h] [rbp-A0h]
int k; // [rsp+24h] [rbp-9Ch]
char *lineptr; // [rsp+28h] [rbp-98h] BYREF
size_t n; // [rsp+30h] [rbp-90h] BYREF
FILE *stream; // [rsp+38h] [rbp-88h]
char s[64]; // [rsp+40h] [rbp-80h] BYREF
char dest[32]; // [rsp+80h] [rbp-40h] BYREF
char s2[24]; // [rsp+A0h] [rbp-20h] BYREF
unsigned __int64 v15; // [rsp+B8h] [rbp-8h]
v15 = __readfsqword(0x28u);
sub_1664(a1, a2, a3);
v3 = time(0LL);
srand(v3);
for ( i = 0; i <= 15; ++i )
s[i] = rand() % 26 + 65;
s[16] = 0;
puts("Random String Generated! Now Shuffle...");
v4 = strlen(s);
strncpy(dest, s, v4);
for ( j = 0; j <= 15; ++j )
{
for ( k = 0; k <= 15; ++k )
{
if ( (j & 1) != 0 )
dest[byte_4020[16 * j + k]] = s[k + 32];
else
s[byte_4020[16 * j + k] + 32] = dest[k];
}
}
printf("Shuffled String: %s\n", dest);
printf("Original String?: ");
fgets(s2, 18, stdin);
s2[strcspn(s2, "\n")] = 0;
if ( !strcmp(s, s2) )
{
lineptr = 0LL;
n = 0LL;
stream = fopen("./flag", "r");
getline(&lineptr, &n, stream);
printf("Match! Here's your flag: %s", lineptr);
free(lineptr);
fclose(stream);
}
else
{
puts("Wrong...");
}
return 0LL;
}
셔플된 문자열을 출력해주고 원래 문자열과 입력받은 문자열을 비교한 후 플래그를 출력해준다.
셔플방식은 다음과 같다.
strncpy(dest, s, v4);
for ( j = 0; j <= 15; ++j )
{
for ( k = 0; k <= 15; ++k )
{
if ( (j & 1) != 0 )
dest[byte_4020[16 * j + k]] = s[k + 32];
else
s[byte_4020[16 * j + k] + 32] = dest[k];
}
}
gdb에서 s[16] = 0에 bp를 걸고 s를 확인했다.

그런데 이 방식으로 하면 segmentation fault가 발생한다.
gdb script를 짜서 출력해도 segmentation fault가 난다. 왜?

다시 보니까 vm 생성하기가 있는데...?
그러면 이거 pwntools로 접속해야하는건가

flag 파일을 넣어주니까 이렇게 뜨긴 하는데 그러면 저거 접속을 어케하지...?
import gdb
ge = gdb.execute
inferior = gdb.selected_inferior()
ge('file ./many-shuffle')
gdb.Breakpoint('*0x555555555430')
ge('run')
rbp = int(gdb.parse_and_eval("$rbp"))
s = bytes(inferior.read_memory(rbp-0x80, 16))
print(s)
ge('c')
그러면 그냥 정석대로 shuffle 활용해서 하라는건가...꼼수쓰지 말고
까비
from pwn import *
arr = [ 11, 8, 3, 4, 1, 0, 14, 13, 15, 9,
12, 6, 2, 5, 7, 10, 15, 4, 8, 11,
6, 7, 13, 2, 12, 3, 5, 14, 10, 0,
1, 9, 4, 12, 14, 5, 13, 6, 9, 10,
1, 0, 11, 15, 2, 7, 3, 8, 10, 8,
15, 3, 4, 6, 0, 11, 1, 13, 9, 7,
5, 2, 12, 14, 11, 6, 9, 15, 2, 1,
10, 14, 3, 12, 13, 0, 5, 4, 8, 7,
9, 4, 11, 5, 6, 15, 8, 0, 3, 1,
10, 13, 2, 14, 12, 7, 10, 14, 9, 7,
8, 13, 3, 11, 12, 15, 2, 0, 4, 5,
6, 1, 5, 4, 13, 1, 0, 2, 9, 11,
12, 7, 8, 10, 6, 14, 15, 3, 4, 8,
5, 2, 10, 15, 11, 7, 0, 1, 12, 3,
14, 6, 9, 13, 13, 14, 15, 11, 0, 2,
10, 4, 7, 6, 9, 1, 5, 3, 8, 12,
14, 2, 3, 5, 10, 1, 7, 0, 9, 13,
12, 11, 4, 6, 15, 8, 3, 11, 14, 10,
6, 4, 7, 1, 2, 13, 15, 0, 12, 9,
5, 8, 13, 15, 1, 2, 12, 10, 3, 7,
9, 6, 8, 5, 0, 4, 11, 14, 0, 14,
4, 13, 6, 1, 10, 5, 3, 12, 7, 11,
15, 2, 8, 9, 11, 2, 8, 7, 5, 3,
9, 13, 4, 15, 0, 1, 6, 12, 14, 10,
11, 1, 8, 0, 12, 13, 4, 14, 10, 6,
15, 7, 9, 5, 3, 2]
p = remote('host1.dreamhack.games', 19201)
p.recvuntil(b'Shuffled String: ')
s1 = list(str(p.recvline()[:-1], 'utf-8'))
s = [0 for i in range(16)]
for j in range(15, -1, -1):
for k in range(15, -1, -1):
if ((j & 1) != 0):
s[k] = s1[arr[16*j+k]]
else:
s1[k] = s[arr[16*j+k]]
print(''.join(s))
p.sendlineafter(b'Original String?: ', ''.join(s))
p.interactive()
from pwn import *
import ctypes
libc = ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(libc.time(0))
s = ''
for i in range(16):
s += chr(libc.rand()%26 + ord('A'))
print(s)
p = remote('host1.dreamhack.games', 21677)
p.sendlineafter(b'Original String?: ', s)
p.interactive()
이 방법으로 해결했다.
안녕하세요, 글 잘 봤습니다. 질문이 있습니다.
1. 제가 초보자라 잘 모르는데 혹시 bp 어떻게 거셨나요?
2. bp 걸고 gdb 에서 finish 해도 작성자분처럼 Match! 가 안뜨고 그냥 프로그램이 끝납니다.(로컬에서 실행했어도 Match는 떠야하는거 아닌가요..)
3. 마지막 코드를 써도 flag는 안나옵니다.. 무엇이 문제인가요?
이에대해 답변 해주시길 부탁드립니다..