(요청)[pwnable.kr] - codemap

해킹대회 문제 풀이 연습장소

Moderator: amesianx

Post Reply
KSH
Posts: 24
Joined: Thu Jul 21, 2016 5:39 pm

(요청)[pwnable.kr] - codemap

Post by KSH » Fri Sep 23, 2016 6:18 pm

intro.png
intro.png (21.16 KiB) Viewed 433 times
나는힙에 많은 정보가 담긴 바이너리를 가지고 있는데 당신은 이것을 어떻게 빠르게 리버싱 할 것인가요?
힌트 : 0x403E65지점이 실행될 때의 EAX와 EBX를 보세요
정도로 해석됩니다.
1.png
1.png (6.88 KiB) Viewed 433 times
메모리에 용량을 할당했는데 문자열의 덩어리가 X12nM7yCJcu0x5u라고 나옵니다.
문제를 읽어보면
question.png
question.png (8.72 KiB) Viewed 433 times
질문에 대한 올바른 답을 적으라고 합니다.
break.png
break.png (13.85 KiB) Viewed 433 times
힌트에 나타난 지점에 브레이크를 걸고 계속해서 실행한 결과로
2.png
2.png (3.34 KiB) Viewed 433 times
3.png
3.png (3.9 KiB) Viewed 433 times
4.png
4.png (3.59 KiB) Viewed 433 times
njqIVnYuX7NcwLc
roKBkoIZGMUKrMb
X12nM7yCJcu0x5u
등의 문자열이 있습니다.

문제에서 요구하는데로 nc 0 9021을 실행시키면
5.png
5.png (7.54 KiB) Viewed 433 times
두번째로 큰 문자열과 세번째로 큰 문자열을 묻습니다.
문자열을 입력했으나 실력이 부족한지 풀어내지 못했습니다.
codemap을 가르쳐주세요

hackhack
Posts: 14
Joined: Mon Sep 26, 2016 1:12 am

Re: (요청)[pwnable.kr] - codemap

Post by hackhack » Wed Sep 28, 2016 8:09 am

printf("I will make 1000 heap chunks with random size\n");
printf("each heap chunk has a random string\n");
printf("press enter to start the memory allocation\n");
sub_AA40B1();
v17 = 0;
v16 = 0;
srand(0);
while ( 1 )
{
v3 = 10000 * rand() % 1337;
v4 = (int (***)(void))operator new(8u);
v5 = v4;
v19 = 0;
if ( v4 )
{
*v4 = (int (**)(void))&off_AAF2EC;
v6 = (10000 * v3 >> 1) + 123;
v7 = (int (**)(void))operator new(8u);
if ( v7 )
{
v7[1] = (int (*)(void))v6;
v5[1] = v7;
v8 = v5;
}
else
{
v5[1] = 0;
v8 = v5;
}
}
else
{
v8 = 0;
}
v19 = -1;
v9 = (**v8)();
v10 = v9 % 0x186A0;
v15 = v9 % 0x186A0;
v11 = (char *)malloc(v9 % 0x186A0);
if ( v10 >= 0x10 )
{
qmemcpy(v18, "abcdefghijklmnopqrstubwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 0x3Fu);
v12 = 0;
do
v11[++v12 - 1] = v18[rand() % 62];
while ( v12 < 0xF );
v11[15] = 0;
if ( v15 > v17 )
{
v17 = v15;
v14 = v11;
}
}
if ( ++v16 >= 0x3E8 )
break;
srand(v16);
}
printf("the allcated memory size of biggest chunk is %d byte\n", v17);
printf("the string inside that chunk is %s\n", v14);
printf("log in to pwnable.kr and anwer some question to get flag.\n");
sub_AA40B1();
return 0;


아이다로 소스코드를 분석해 보면, 0x3E8 번동안 루프를 돌면서, 메모리를 할당하고, rand() 해서 나오는거에 따라 문자열을 생성하여 저장하는 것을 알 수 있습니다.
이 문제에서 묻는것은, 크기가 2, 3, 4번째로 크게 할당된 메모리에 저장된 내용을 뽑아내는 것입니다.

저같은 경우에는, 다음 부분에 브포를 걸고, ida python 을 이용해서, 자동으로 할당된 주소와 크기를 리스트에 저장하는 방법을 이용했습니다.
0.png
0.png (3.77 KiB) Viewed 424 times

Code: Select all

from idaapi import *

ggg = []

def getStr(addr):
	s = ''
	i = 0
	while 1:
		r = DbgByte(addr + i)
		i += 1
		if r == None or r == 0:
			break
		s += chr(r)
	return s

class MyDbgHook(DBG_Hooks):
    def dbg_bpt(self, tid, ea):
    	global ggg
        print "Break point at 0x%x pid=%d" % (ea, tid)
        if GetRegValue('eip') != 0x1383E88:
        	ggg.append((GetRegValue('eax'), GetRegValue('esi')))
        	idaapi.continue_process()
        return 0

try:
    if debughook:
        print("Removing previous hook ...")
        debughook.unhook()
except:
    pass

# Install the debug hook
debughook = MyDbgHook()
debughook.hook()

# Start debugging
run_requests()
브포를 걸고 이 코드를 실행하면, malloc 호출 바로 다음 위치에서 리턴값과 사이즈를 ggg 리스트에 저장해놓습니다.

그리고, 다음 코드를 실행시켜서 자동으로 정렬하고, 해당 영역의 스트링을 가져옵니다.

Code: Select all

a = sorted(ggg, key=lambda x: x[1], reverse=True)
for i in range(10):
	print getStr(a[i][0])

Post Reply

Who is online

Users browsing this forum: No registered users and 21 guests