문제를 열어보면
파일이 있다.
참고해서 roots.cpio 파일을 열어본다. 이 파일 시스템은 우리가 문제 서버를 nc로 접속했을 경우와 동일하다.
우리는 ughc binary를 이용해서 flag를 읽어야 한다.
ughc를 분석하자.
int __fastcall main(int argc, const char **argv, const char **envp)
{
int cha; // eax
int i; // [rsp+10h] [rbp-B50h]
int j; // [rsp+14h] [rbp-B4Ch]
int k; // [rsp+18h] [rbp-B48h]
unsigned __int64 idx; // [rsp+20h] [rbp-B40h]
__int64 val; // [rsp+28h] [rbp-B38h]
u32 *fd2; // [rsp+30h] [rbp-B30h]
__int64 fd; // [rsp+38h] [rbp-B28h]
__int64 buf[32]; // [rsp+40h] [rbp-B20h] BYREF
int data[512]; // [rsp+140h] [rbp-A20h] BYREF
__int64 v14; // [rsp+940h] [rbp-220h]
__int64 v15; // [rsp+948h] [rbp-218h]
char v16[496]; // [rsp+950h] [rbp-210h] BYREF
unsigned __int64 canary; // [rsp+B48h] [rbp-18h]
canary = __readfsqword(0x28u);
v14 = 0LL;
v15 = 0LL;
memset(v16, 0, sizeof(v16));
memset(data, 0, sizeof(data));
memset(buf, 0, sizeof(buf));
idx = 0LL;
val = 0LL;
initialize();
fd = fopen64("attack.ugh", "rb");
if ( fd )
{
fgetws(data, 512LL, fd);
if ( wcswcs(data, dword_496038) ) // "우", "가", "아" "-", "!"
{
for ( i = 7; i < j_wcslen(data); ++i )
{
cha = data[i];
if ( cha == 0xC6B0 ) // 0xC6B0 = "우"
{
++val;
}
else if ( cha <= 0xC6B0 )
{
if ( cha == 0xC559 ) // 0xC559 = "앙"
{
val = 0LL;
}
else if ( cha <= 0xC559 )
{
if ( cha == 0xC54D ) // 0xC54D = "앍"
{
if ( buf[idx] )
{
while ( data[i] == 0xADF8 ) // 0xADF8 = "그"
--i;
}
}
else if ( cha <= 0xC54D )
{
if ( cha == 0xAC00 ) // "가"
{
val *= 2LL;
}
else if ( cha <= 0xAC00 ) // 0xAC00 = "가"
{
if ( cha == '~' )
{
if ( idx )
{
--idx;
val = 0LL;
}
}
else if ( cha <= '~' )
{
if ( cha == '?' )
{
printf("%lx\n", buf[idx]);
}
else if ( cha <= '?' )
{
if ( cha == '!' )
{
if ( idx <= 0x1F )
{
++idx;
val = 0LL;
}
}
else if ( cha == '-' )
{
buf[idx] = val;
val = 0LL;
}
}
}
}
}
}
}
}
if ( argc > 1 )
{
fd2 = stdout;
for ( j = 1; j < argc; ++j )
{
if ( !j_strncmp_ifunc(argv[j], "-logfile", 8LL) )
fd2 = fopen64(argv[j + 1], "w");
if ( !j_strncmp_ifunc(argv[j], "-debug", 6LL) )
{
fwrite("debug:", 1LL, 6LL, fd2);
for ( k = 0; buf[k]; ++k )
fputc(buf[k], fd2);
}
}
}
return 0;
}
else
{
puts("UGH: UGAA--!! UGH UGA!!!");
return -2;
}
}
else
{
puts("UGH: UGA UGA UGA!!!");
return -1;
}
}
우 가 아 — ~ ! ? 등 다양한 기호를 통해 데이터를 읽고 쓸수 있다.
문제의 목표는 /home/root/flag를 읽는 것이다. setuid가 걸려 있어 권한은 상관 없을 것이다.
./ughc -logfile test -debug 이런 방식으로 만들어 test에 buf에 쓰여진 값을 넣을 수 있다.
이 문제는 다른 문제와 다르게 shell? 얻는 것 보다 다양한 방법을 생각해야 할 거 같다. logfile을 어떤 것으로 잡느냐에 따라 우리는 root 권한을 가진채 아무 파일에 원하는 내용을 적을 수 있을 것이다!!!